View Javadoc

1   /*****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  
21  package org.apache.james.postage.result;
22  
23  import org.apache.commons.collections.map.HashedMap;
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  
27  import java.io.FileOutputStream;
28  import java.io.IOException;
29  import java.io.OutputStreamWriter;
30  import java.io.File;
31  import java.util.ArrayList;
32  import java.util.Date;
33  import java.util.Iterator;
34  import java.util.List;
35  import java.util.Map;
36  import java.util.LinkedHashMap;
37  
38  public class PostageRunnerResultImpl implements PostageRunnerResult {
39  
40      private static Log log = LogFactory.getLog(PostageRunnerResultImpl.class);
41  
42      private Map m_matchedMailResults = initMatchedMailResultContainer();
43  
44      private final Map m_unmatchedMailResults = new HashedMap();
45  
46      private List m_errors = initErrorResultContainer();
47  
48      private List m_jvmStatistics = initMatchedJVMStatisticsResultContainer();
49  
50      private long m_TimestampFirstResult = -1;
51  
52      private long m_TimestampLastResult = -1;
53  
54      private long m_matchedMailCounter = 0;
55  
56      private long m_validMailCounter = 0;
57  
58      private Map  m_environmentInfo = new LinkedHashMap();
59  
60      public void addNewMailRecord(MailProcessingRecord mailProcessingRecord) {
61  
62          if (m_TimestampFirstResult <= 0) m_TimestampFirstResult = System.currentTimeMillis();
63          m_TimestampLastResult = System.currentTimeMillis();
64  
65          MailProcessingRecord prevMailProcessingRecord = (MailProcessingRecord)m_unmatchedMailResults.put(mailProcessingRecord.getMailId(), mailProcessingRecord);
66          if (prevMailProcessingRecord != null) {
67              log.error("mail result already contained in unmatched list!");
68          }
69      }
70  
71      public synchronized MailProcessingRecord matchMailRecord(MailProcessingRecord mailProcessingRecord) {
72          if (mailProcessingRecord == null) return null;
73          String mailId = mailProcessingRecord.getMailId();
74          if (mailId == null) return null;
75  
76          if (m_unmatchedMailResults.containsKey(mailId)) {
77              // merge both mail result objects into one and move it to matched list
78              MailProcessingRecord match = (MailProcessingRecord)m_unmatchedMailResults.remove(mailId);
79              log.info("matched test mail having id = " + mailId + " received by queue = " + mailProcessingRecord.getReceivingQueue());
80  
81              match.merge(mailProcessingRecord); // copy new data to saved record
82  
83              m_matchedMailResults.put(mailId, match);
84              m_matchedMailCounter++;
85              return match;
86          } else if (m_matchedMailResults.containsKey(mailId)) {
87              log.warn("mail already matched for mailId = " + mailId);
88          } else {
89              log.warn("mail match candidate has unknown (purged?) mailId = " + mailId);
90          }
91  
92          return null;
93      }
94      
95      public void recordValidatedMatch(MailProcessingRecord matchedAndMergedRecord) {
96          if (!m_matchedMailResults.values().contains(matchedAndMergedRecord)) {
97              log.error("cannot record validation result for (already written?) result having id " 
98                         + matchedAndMergedRecord.getMailId());
99              return;
100         }
101         
102         if (matchedAndMergedRecord.isReceivedValid()) m_validMailCounter++;
103     }
104 
105     public void addJVMResult(JVMResourcesRecord jvmResourcesRecord) {
106         m_jvmStatistics.add(jvmResourcesRecord);
107     }
108 
109     public void setEnvironmentDescription(Map descriptionItems) {
110         m_environmentInfo.putAll(descriptionItems);
111     }
112 
113     public long getUnmatchedMails() {
114         return m_unmatchedMailResults.size();
115     }
116 
117     public long getMatchedMails() {
118         return m_matchedMailCounter;
119     }
120 
121     public long getValidMails() {
122         return m_validMailCounter;
123     }
124 
125     public void writeMailResults(OutputStreamWriter outputStreamWriter, boolean flushOnlyMatched) throws IOException {
126         writeMatchedMailResults(outputStreamWriter);
127         if (!flushOnlyMatched) {
128             writeUnmatchedMailResults(outputStreamWriter);
129             writeGeneralData(outputStreamWriter);
130         }
131     }
132 
133     private void writeUnmatchedMailResults(OutputStreamWriter outputStreamWriter) throws IOException {
134         writeMailResults(m_unmatchedMailResults, outputStreamWriter);
135         outputStreamWriter.flush();
136     }
137 
138     private void writeMatchedMailResults(OutputStreamWriter outputStreamWriter) throws IOException {
139         Map writeResults = m_matchedMailResults; // keep current results for writing
140         m_matchedMailResults = initMatchedMailResultContainer(); // establish new map for further unwritten results
141         writeMailResults(writeResults, outputStreamWriter);
142         outputStreamWriter.flush();
143     }
144 
145     private void writeGeneralData(OutputStreamWriter outputStreamWriter) throws IOException {
146         outputStreamWriter.write("start," + m_TimestampFirstResult + "," + new Date(m_TimestampFirstResult) + "\r\n");
147         outputStreamWriter.write("end," + m_TimestampLastResult + "," + new Date(m_TimestampLastResult) + "\r\n");
148         outputStreamWriter.write("current," + System.currentTimeMillis() + "," + new Date() + "\r\n");
149 
150         Iterator iterator = m_environmentInfo.keySet().iterator();
151         while (iterator.hasNext()) {
152             String elementName = (String)iterator.next();
153             String elementValue = (String)m_environmentInfo.get(elementName);
154             outputStreamWriter.write(elementName + "," + elementValue + "\r\n");
155         }
156     }
157 
158     public long getTimestampFirstResult() {
159         return m_TimestampFirstResult;
160     }
161 
162     public long getTimestampLastResult() {
163         return m_TimestampLastResult;
164     }
165 
166     public void addError(int errorNumber, String errorMessage) {
167         m_errors.add(new ErrorRecord(errorNumber, errorMessage));
168     }
169 
170     public long getErrorCount() {
171         return m_errors.size();
172     }
173 
174     private void writeMailResults(Map mailResults, OutputStreamWriter outputStreamWriter) throws IOException {
175         Iterator iterator = mailResults.values().iterator();
176         while (iterator.hasNext()) {
177             MailProcessingRecord record = (MailProcessingRecord)iterator.next();
178             String resultString = record.writeData().toString();
179             outputStreamWriter.write(resultString);
180         }
181     }
182 
183     private HashedMap initMatchedMailResultContainer() {
184         return new HashedMap();
185     }
186 
187     private List initMatchedJVMStatisticsResultContainer() {
188         return new ArrayList();
189     }
190 
191     private List initErrorResultContainer() {
192         return new ArrayList();
193     }
194 
195     public void writeResults(String filenameMailResults, String filenameJVMStatistics, String filenameErrors, boolean flushMatchedMailOnly) {
196         if (filenameMailResults != null) writeMailResults(filenameMailResults, flushMatchedMailOnly);
197         if (filenameJVMStatistics != null) writeJVMStatistics(filenameJVMStatistics);
198         if (filenameErrors != null) writeErrors(filenameErrors);
199     }
200 
201     public void writeMailResults(String filenameMailResults, boolean flushMatchedMailOnly) {
202        FileOutputStream outputStream = null;
203        OutputStreamWriter outputStreamWriter = null;
204        try {
205            outputStream = new FileOutputStream(filenameMailResults, true);
206            outputStreamWriter = new OutputStreamWriter(outputStream);
207            if (new File(filenameMailResults).length() <= 0) outputStreamWriter.write(MailProcessingRecord.writeHeader().toString());
208            writeMailResults(outputStreamWriter, flushMatchedMailOnly);
209        } catch (IOException e) {
210            log.error("error writing mail results to file " + filenameMailResults, e);
211        } finally {
212            try {
213                if (outputStreamWriter != null) outputStreamWriter.close();
214                if (outputStream != null) outputStream.close();
215                log.info("postage mail results completely written to file " + filenameMailResults);
216            } catch (IOException e) {
217                log.error("error closing stream", e);
218            }
219        }
220     }
221 
222     public void writeJVMStatistics(String filenameJVMStatistics) {
223         FileOutputStream outputStream = null;
224         OutputStreamWriter outputStreamWriter = null;
225         try {
226             outputStream = new FileOutputStream(filenameJVMStatistics, true);
227             outputStreamWriter = new OutputStreamWriter(outputStream);
228             if (new File(filenameJVMStatistics).length() <= 0) outputStreamWriter.write(JVMResourcesRecord.writeHeader().toString());
229             writeJVMStatisticsResults(outputStreamWriter);
230         } catch (IOException e) {
231             log.error("error writing JVM statistic results to file " + filenameJVMStatistics, e);
232         } finally {
233             try {
234                 if (outputStreamWriter != null) outputStreamWriter.close();
235                 if (outputStream != null) outputStream.close();
236                 log.info("postage JVM statistic results completely written to file " + filenameJVMStatistics);
237             } catch (IOException e) {
238                 log.error("error closing stream", e);
239             }
240         }
241     }
242 
243     private void writeJVMStatisticsResults(OutputStreamWriter outputStreamWriter) throws IOException {
244         List unwrittenResults = m_jvmStatistics;
245         m_jvmStatistics = initMatchedJVMStatisticsResultContainer();
246         Iterator iterator = unwrittenResults.iterator();
247         while (iterator.hasNext()) {
248             JVMResourcesRecord record = (JVMResourcesRecord)iterator.next();
249             String resultString = record.writeData().toString();
250             outputStreamWriter.write(resultString);
251         }
252     }
253 
254     public void writeErrors(String filenameErrors) {
255         FileOutputStream outputStream = null;
256         OutputStreamWriter outputStreamWriter = null;
257         try {
258             outputStream = new FileOutputStream(filenameErrors, true);
259             outputStreamWriter = new OutputStreamWriter(outputStream);
260 
261             if (new File(filenameErrors).length() <= 0) {
262                 outputStreamWriter.write("timestamp,number,message\r\n");
263             }
264 
265             List unwrittenResults = m_errors;
266             m_errors = initErrorResultContainer();
267             Iterator iterator = unwrittenResults.iterator();
268             while (iterator.hasNext()) {
269                 ErrorRecord record = (ErrorRecord)iterator.next();
270 
271                 StringBuffer resultString = new StringBuffer();
272                 resultString.append(record.m_timestamp).append(",");
273                 resultString.append(record.m_number).append(",");
274                 resultString.append(record.m_message).append(",");
275                 resultString.append("\r\n");
276 
277                 outputStreamWriter.write(resultString.toString());
278             }
279         } catch (IOException e) {
280             log.error("error writing JVM statistic results to file " + filenameErrors, e);
281         } finally {
282             try {
283                 if (outputStreamWriter != null) outputStreamWriter.close();
284                 if (outputStream != null) outputStream.close();
285                 log.info("postage JVM statistic results completely written to file " + filenameErrors);
286             } catch (IOException e) {
287                 log.error("error closing stream", e);
288             }
289         }
290     }
291 
292 }
293 
294 class ErrorRecord {
295     long m_timestamp = -1;
296     int m_number = -1;
297     String m_message = null;
298 
299     public ErrorRecord(int m_number, String m_message) {
300         this.m_timestamp = System.currentTimeMillis();
301         this.m_number = m_number;
302         this.m_message = m_message;
303     }
304 }