/* * Copyright 2003,2004 Colin Crist * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package hermes.impl; import hermes.Hermes; import hermes.HermesAuditListener; import hermes.HermesAuditLog; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.text.DateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; import org.apache.log4j.Category; /** * Writes messages to disk for audit. A bit srappy in places! * * @author colincrist@hermesjms.com */ public class DefaultHermesLogImpl implements HermesAuditLog { private static final Category cat = Category.getInstance(DefaultHermesLogImpl.class); private static final String SEPARATOR = System.getProperty("file.separator"); private String baseDirName = "."; private Hermes hermes; private boolean active = false; private HermesAuditListener auditListener; private Map readMsgsInTx = new HashMap(); private Map writeMsgsInTx = new HashMap(); private Map filesInTx = new HashMap(); /** * @author colincrist@hermesjms.com * @version $Id: DefaultHermesLogImpl.java,v 1.2 2004/05/08 15:15:45 * colincrist Exp $ */ public DefaultHermesLogImpl(Hermes hermes, String baseDirName, boolean create, boolean active) throws IOException { super(); this.active = active; this.hermes = hermes; File baseDir = new File(baseDirName); if (baseDir.exists()) { if (baseDir.isDirectory()) { // OK } else { throw new IOException("Audit log dir " + baseDirName + " already exists as a file, reverting to '.'"); } } else { if (create) { baseDir.mkdir(); } else { throw new IOException("Audit log dir " + baseDirName + " does not exist, reverting to '.'"); } } this.baseDirName = baseDirName; } /* * (non-Javadoc) * * @see org.metastuff.hermes.HermesAuditLog#onRead(java.lang.String, * javax.jms.Destination, javax.jms.Message) */ public void onRead(Destination from, Collection messages) { if (active) { try { File file = getAuditFile("read@", from); Collection c = (Collection) readMsgsInTx.get(file); c.addAll(messages); } catch (JMSException e) { cat.error(e.getMessage(), e); } catch (IOException e) { cat.error(e.getMessage(), e); } } } /* * (non-Javadoc) * * @see org.metastuff.hermes.HermesAuditLog#onWrite(java.lang.String, * javax.jms.Destination, javax.jms.Message) */ public void onWrite(Destination from, Collection messages) { if (active) { try { File file = getAuditFile("write@", from); Collection c = (Collection) writeMsgsInTx.get(file); c.addAll(messages); } catch (JMSException e) { cat.error(e.getMessage(), e); } catch (IOException e) { cat.error(e.getMessage(), e); } } } public File getAuditFile(String prefix, Destination dest) throws IOException, JMSException { DateFormat dateFormat = DateFormat.getDateInstance(); Date now = new Date(); String userDirName = System.getProperty("user.name"); String dateDirName = dateFormat.format(new Date()); String hermesDirName = hermes.getId(); String destDirName = hermes.getDestinationName(dest); String fileName = prefix + now.getHours() + "_" + now.getMinutes() + "_" + now.getSeconds() + ".xml"; destDirName = destDirName.replaceAll("queue:///", ""); // MQ hack. String auditFileName = baseDirName + SEPARATOR + userDirName + SEPARATOR + dateDirName + SEPARATOR + hermesDirName + SEPARATOR + destDirName + SEPARATOR + fileName; File auditFile; if (filesInTx.containsKey(auditFileName)) { auditFile = (File) filesInTx.get(auditFileName); } else { File userDir = new File(baseDirName + SEPARATOR + userDirName); if (!userDir.exists()) { userDir.mkdir(); } File dateDir = new File(userDir.getPath() + SEPARATOR + dateDirName); if (!dateDir.exists()) { dateDir.mkdir(); } File hermesDir = new File(dateDir.getPath() + SEPARATOR + hermesDirName); if (!hermesDir.exists()) { hermesDir.mkdir(); } File destDir = new File(hermesDir.getPath() + SEPARATOR + destDirName); if (!destDir.exists()) { destDir.mkdir(); } auditFile = new File(destDir.getPath() + SEPARATOR + fileName); filesInTx.put(auditFileName, auditFile); readMsgsInTx.put(auditFile, new ArrayList()); writeMsgsInTx.put(auditFile, new ArrayList()); if (!auditFile.exists()) { auditFile.createNewFile(); } } return auditFile; } /* * (non-Javadoc) * * @see hermes.HermesAuditLog#onRead(hermes.Hermes, javax.jms.Destination, * javax.jms.Message) */ public void onRead(Destination from, Message message) { if (active) { List list = new ArrayList(); list.add(message); onRead(from, list); } } /* * (non-Javadoc) * * @see hermes.HermesAuditLog#onWrite(hermes.Hermes, javax.jms.Destination, * javax.jms.Message) */ public void onWrite(Destination to, Message message) { if (active) { List list = new ArrayList(); list.add(message); onWrite(to, list); } } /** * @return Returns the active. */ public boolean isActive() { return active; } /** * @param active * The active to set. */ public void setActive(boolean active) { this.active = active; if (!active) { rollback(); } } /* * (non-Javadoc) * * @see hermes.HermesAuditLog#commit() */ public void commit() { if (active) { for (Iterator iter = readMsgsInTx.entrySet().iterator(); iter.hasNext();) { try { Map.Entry entry = (Map.Entry) iter.next(); FileOutputStream ostream = new FileOutputStream((File) entry.getKey()); Collection messages = (Collection) entry.getValue(); hermes.toXML(messages, ostream); ostream.flush(); ostream.close(); } catch (Exception e) { cat.error("unable to log messages: " + e.getMessage(), e); Hermes.ui.getDefaultMessageSink().add("Unable to log messages for audit: " + e.getMessage()); } } for (Iterator iter = writeMsgsInTx.entrySet().iterator(); iter.hasNext();) { try { Map.Entry entry = (Map.Entry) iter.next(); FileOutputStream ostream = new FileOutputStream((File) entry.getKey()); Collection messages = (Collection) entry.getValue(); hermes.toXML(messages, ostream); ostream.flush(); ostream.close(); } catch (Exception e) { cat.error("unable to log messages: " + e.getMessage(), e); Hermes.ui.getDefaultMessageSink().add("Unable to log messages for audit: " + e.getMessage()); } } readMsgsInTx.clear(); writeMsgsInTx.clear(); filesInTx.clear(); } } /* * (non-Javadoc) * * @see hermes.HermesAuditLog#rollback() */ public void rollback() { readMsgsInTx.clear(); writeMsgsInTx.clear(); filesInTx.clear(); } /* * (non-Javadoc) * * @see hermes.HermesAuditLog#setListener(hermes.HermesAuditListener) */ public void setListener(HermesAuditListener auditListener) { this.auditListener = auditListener; } }