package cl.alma.camel.acslog;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.concurrent.ExecutorService;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.apache.camel.impl.DefaultConsumer;
import org.apache.camel.impl.DefaultExchange;
import org.apache.camel.impl.DefaultMessage;
import org.apache.commons.io.FilenameUtils;
import com.cosylab.logging.engine.ACS.ACSRemoteErrorListener;
import com.cosylab.logging.engine.ACS.ACSRemoteLogListener;
import com.cosylab.logging.engine.ACS.ACSRemoteRawLogListener;
import com.cosylab.logging.engine.audience.Audience;
import com.cosylab.logging.engine.audience.Audience.AudienceInfo;
import com.cosylab.logging.engine.log.ILogEntry;
import com.cosylab.logging.engine.log.LogTypeHelper;
import alma.acs.logging.engine.io.IOHelper;
import alma.acs.logging.engine.io.IOPorgressListener;
/**
*
* @author atejeda
*
*/
public class ACSLogConsumerXML extends DefaultConsumer implements ACSRemoteLogListener,
ACSRemoteRawLogListener, ACSRemoteErrorListener, IOPorgressListener {
private final ACSLogEndpoint endpoint;
private String xmlPath = null;
private File xmlDir = null;
private int filesread = 0;
private long logsparsed = 0;
private long logsread = 0;
private IOHelper ioHelper = null;
/**
* Constructor, set the xml directory path from the endpoint options,
* @param endpoint
* @param processor
*/
public ACSLogConsumerXML(ACSLogEndpoint endpoint, Processor processor) {
super(endpoint, processor);
this.endpoint = endpoint;
this.xmlPath = this.endpoint.getXml();
}
/**
* Start the common validation files and reading process
* of the log, if is a file, or the logs located at that directory.
*
* Invoke {@link #doStop()} whe all logs files were processed.
*/
@Override
protected void doStart() throws Exception {
log.info("Using directory ", this.xmlPath);
this.xmlDir = new File(this.xmlPath);
if(!this.xmlDir.canRead() || !this.xmlDir.exists()) {
log.info("Can't read " + this.xmlPath + ", exists?");
} else if(this.xmlDir.isFile()) {
this.readLog(this.xmlDir);
} else {
this.readLogs();
}
this.doStop();
}
/**
* Do nothing.
*/
@Override
protected void doStop() throws Exception {
log.info("Stops");
}
/**
* If the endpoint option were a directory, it will start reading
* all logs from that directory with an .xml extension.
*/
public void readLogs() {
try {
for(File nfile : this.xmlDir.listFiles(this.xmlFileFilter())) {
this.readLog(nfile);
}
} catch (Exception e) {
log.error("Can't read the file..." + e.toString());
}
}
/**
* Using ACS (ALMA Common Software) loggin api, it will start reading
* the log xml file.
* @param logFile the xml log to read.
*/
public void readLog(File logFile) {
this.logsread = 0;
this.logsparsed = 0;
try {
BufferedReader bufferReader = new BufferedReader(new FileReader(logFile));
this.ioHelper = new IOHelper();
this.ioHelper.setDiscardLevel(this.getLogDiscardLevel());
this.ioHelper.setAudience(this.getAudience());
this.ioHelper.loadLogs(bufferReader, this, this, this, this);
this.filesread++;
} catch (FileNotFoundException e) {
log.error(e.getMessage());
} catch (Exception e) {
log.error(e.getMessage());
}
log.info("logs read :" + this.logsread);
log.info("logs parsed :" + this.logsparsed);
log.info("logs file read :" + this.filesread);
}
/**
* It's an anonymous implementation for filtering
* xml files with xml entension.
* @return a file filter for xml file extension.
*/
public FileFilter xmlFileFilter() {
return new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isFile() &&
FilenameUtils.isExtension(pathname.getName(), "xml");
}
};
}
/**
* From a message in byte[], create a Camel exchange.
* @param messageBody the body of the message in a Camel context.
* @return a Camel exchange.
*/
public Exchange createExchange(byte[] messageBody) {
Exchange exchange = new DefaultExchange(this.endpoint.getCamelContext(),
this.endpoint.getExchangePattern());
Message message = new DefaultMessage();
//message.setHeader
message.setBody(messageBody);
exchange.setIn(message);
return exchange;
}
/**
* Returns the audience for reading the log, defined in the endpoint,
* ACS logging api use this as a filter.
* @return the audience, by default: Enginner.
*/
public Audience getAudience() {
String audienceString = this.endpoint.getAudience();
Audience audience;
audience = AudienceInfo.fromShortName(audienceString).getAudience();
if(audience == null) {
audience = AudienceInfo.ENGINEER.getAudience();
}
return audience;
}
/**
* Returns the discard level for reading the log, defined in the endpoint,
* ACS logging api use this as a filter.
* @return the discard level, by default: Debug.
*/
public LogTypeHelper getLogDiscardLevel() {
String logdiscardString = this.endpoint.getDiscard();
LogTypeHelper logDiscard;
logDiscard = LogTypeHelper.fromLogTypeDescription(logdiscardString);
if(logDiscard == null) {
logDiscard= LogTypeHelper.DEBUG;
}
return logDiscard;
}
/**
* Returns the log level for reading the log, defined in the endpoint,
* ACS logging api use this as a filter.
* @return the log level, by default: Info.
*/
public LogTypeHelper getLogLevel() {
String loglevelString = this.endpoint.getLevel();
LogTypeHelper loglevel;
loglevel = LogTypeHelper.fromLogTypeDescription(loglevelString);
if(loglevel == null) {
loglevel= LogTypeHelper.INFO;
}
return loglevel;
}
/**
* Receive a log entry from the xml files, updates the read log count
* and the read log parsed count, also add the "origin" field to the
* data file of the ACS logging api structure, the purpuse is to
* identify the origin of this log, eg.: my-localhost-name.
* <br/>
* Also it will create the Camel exchange to be sent to the processor.
*/
@Override
public void logEntryReceived(ILogEntry logEntry) {
this.logsread++;
try {
logEntry.addData("origin", this.endpoint.getOrigin());
Exchange exchange = this.createExchange(logEntry.toXMLString().getBytes());
this.getProcessor().process(exchange);
this.logsparsed++;
} catch (Exception e) {
log.error(e.toString());
}
}
/**
* Not implemented and used, forced by the observer interface.
*/
@Override
public void logsRead(int numOfLogs) {}
/**
* Not implemented and used, forced by the observer interface.
*/
@Override
public void xmlEntryReceived(String xmlLogString) {}
/**
* Not implemented and used, forced by the observer interface.
*/
@Override
public void logsWritten(int numOfLogs) {}
/**
* Not implemented and used, forced by the observer interface.
*/
@Override
public void errorReceived(String xml) {}
/**
* Not implemented and used, forced by the observer interface.
*/
@Override
public void bytesRead(long nBytes) {}
/**
* Not implemented and used, forced by the observer interface.
*/
@Override
public void bytesWritten(long nBytes) {}
}