Fix for issue #17. Error when posting to mailinglist is now reported back to user as NNTP error.
1.1 --- a/src/org/sonews/daemon/command/PostCommand.java Sun Sep 11 17:01:19 2011 +0200
1.2 +++ b/src/org/sonews/daemon/command/PostCommand.java Sun Sep 11 17:36:47 2011 +0200
1.3 @@ -22,6 +22,7 @@
1.4 import java.io.ByteArrayOutputStream;
1.5 import java.sql.SQLException;
1.6 import java.util.Arrays;
1.7 +import java.util.logging.Level;
1.8 import javax.mail.MessagingException;
1.9 import javax.mail.internet.AddressException;
1.10 import javax.mail.internet.InternetHeaders;
1.11 @@ -110,8 +111,8 @@
1.12
1.13 // add the header entries for the article
1.14 article.setHeaders(headers);
1.15 - } catch (MessagingException e) {
1.16 - e.printStackTrace();
1.17 + } catch (MessagingException ex) {
1.18 + Log.get().log(Level.INFO, ex.getLocalizedMessage(), ex);
1.19 conn.println("500 posting failed - invalid header");
1.20 state = PostState.Finished;
1.21 break;
1.22 @@ -213,8 +214,7 @@
1.23 controlMessage(conn, article);
1.24 } else if (article.getHeader(Headers.SUPERSEDES)[0].length() > 0) {
1.25 supersedeMessage(conn, article);
1.26 - } else // Post the article regularily
1.27 - {
1.28 + } else { // Post the article regularily
1.29 // Circle check; note that Path can already contain the hostname here
1.30 String host = Config.inst().get(Config.HOSTNAME, "localhost");
1.31 if (article.getHeader(Headers.PATH)[0].indexOf(host + "!", 1) > 0) {
1.32 @@ -234,8 +234,7 @@
1.33 if (group.isMailingList() && !conn.isLocalConnection()) {
1.34 // Send to mailing list; the Dispatcher writes
1.35 // statistics to database
1.36 - Dispatcher.toList(article, group.getName());
1.37 - success = true;
1.38 + success = Dispatcher.toList(article, group.getName());
1.39 } else {
1.40 // Store in database
1.41 if (!StorageManager.current().isArticleExisting(article.getMessageID())) {
1.42 @@ -254,7 +253,7 @@
1.43 conn.println("240 article posted ok");
1.44 FeedManager.queueForPush(article);
1.45 } else {
1.46 - conn.println("441 newsgroup not found");
1.47 + conn.println("441 newsgroup not found or configuration error");
1.48 }
1.49 } catch (AddressException ex) {
1.50 Log.get().warning(ex.getMessage());
2.1 --- a/src/org/sonews/mlgw/Dispatcher.java Sun Sep 11 17:01:19 2011 +0200
2.2 +++ b/src/org/sonews/mlgw/Dispatcher.java Sun Sep 11 17:36:47 2011 +0200
2.3 @@ -15,12 +15,12 @@
2.4 * You should have received a copy of the GNU General Public License
2.5 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2.6 */
2.7 -
2.8 package org.sonews.mlgw;
2.9
2.10 import java.io.IOException;
2.11 import java.util.ArrayList;
2.12 import java.util.List;
2.13 +import java.util.logging.Level;
2.14 import java.util.regex.Matcher;
2.15 import java.util.regex.Pattern;
2.16 import javax.mail.Address;
2.17 @@ -43,19 +43,16 @@
2.18 * @author Christian Lins
2.19 * @since sonews/0.5.0
2.20 */
2.21 -public class Dispatcher
2.22 -{
2.23 +public class Dispatcher {
2.24
2.25 - static class PasswordAuthenticator extends Authenticator
2.26 - {
2.27 + static class PasswordAuthenticator extends Authenticator {
2.28
2.29 @Override
2.30 - public PasswordAuthentication getPasswordAuthentication()
2.31 - {
2.32 + public PasswordAuthentication getPasswordAuthentication() {
2.33 final String username =
2.34 - Config.inst().get(Config.MLSEND_USER, "user");
2.35 + Config.inst().get(Config.MLSEND_USER, "user");
2.36 final String password =
2.37 - Config.inst().get(Config.MLSEND_PASSWORD, "mysecret");
2.38 + Config.inst().get(Config.MLSEND_PASSWORD, "mysecret");
2.39
2.40 return new PasswordAuthentication(username, password);
2.41 }
2.42 @@ -66,8 +63,7 @@
2.43 * @param listPostValue
2.44 * @return The matching email address or null
2.45 */
2.46 - private static String chunkListPost(String listPostValue)
2.47 - {
2.48 + private static String chunkListPost(String listPostValue) {
2.49 // listPostValue is of form "<mailto:dev@openoffice.org>"
2.50 Pattern mailPattern = Pattern.compile("(\\w+[-|.])*\\w+@(\\w+.)+\\w+");
2.51 Matcher mailMatcher = mailPattern.matcher(listPostValue);
2.52 @@ -87,8 +83,7 @@
2.53 * @return null or fitting group name for the given message.
2.54 */
2.55 private static List<String> getGroupFor(final Message msg, final boolean fallback)
2.56 - throws MessagingException, StorageBackendException
2.57 - {
2.58 + throws MessagingException, StorageBackendException {
2.59 List<String> groups = null;
2.60
2.61 // Is there a List-Post header?
2.62 @@ -101,13 +96,16 @@
2.63 }
2.64
2.65 if (listPost != null && listPost.length > 0
2.66 - && !"".equals(listPost[0]) && chunkListPost(listPost[0]) != null) {
2.67 + && !"".equals(listPost[0]) && chunkListPost(listPost[0]) != null) {
2.68 // listPost[0] is of form "<mailto:dev@openoffice.org>"
2.69 listPost[0] = chunkListPost(listPost[0]);
2.70 listPostAddr = new InternetAddress(listPost[0], false);
2.71 groups = StorageManager.current().getGroupsForList(listPostAddr.getAddress());
2.72 } else if (fallback) {
2.73 - Log.get().info("Using fallback recipient discovery for: " + msg.getSubject());
2.74 + StringBuilder strBuf = new StringBuilder();
2.75 + strBuf.append("Using fallback recipient discovery for: ");
2.76 + strBuf.append(msg.getSubject());
2.77 + Log.get().info(strBuf.toString());
2.78 groups = new ArrayList<String>();
2.79 // Fallback to TO/CC/BCC addresses
2.80 Address[] to = msg.getAllRecipients();
2.81 @@ -131,8 +129,7 @@
2.82 * crosspostings in different mailing lists.
2.83 * @param msg
2.84 */
2.85 - public static boolean toGroup(final Message msg)
2.86 - {
2.87 + public static boolean toGroup(final Message msg) {
2.88 if (msg == null) {
2.89 throw new IllegalArgumentException("Argument 'msg' must not be null!");
2.90 }
2.91 @@ -144,7 +141,7 @@
2.92
2.93 // Check if this mail is already existing the storage
2.94 boolean updateReq =
2.95 - StorageManager.current().isArticleExisting(article.getMessageID());
2.96 + StorageManager.current().isArticleExisting(article.getMessageID());
2.97
2.98 List<String> newsgroups = getGroupFor(msg, !updateReq);
2.99 List<String> oldgroups = new ArrayList<String>();
2.100 @@ -170,7 +167,11 @@
2.101 groups.append(',');
2.102 }
2.103 }
2.104 - Log.get().info("Posting to group " + groups.toString());
2.105 +
2.106 + StringBuilder strBuf = new StringBuilder();
2.107 + strBuf.append("Posting to group ");
2.108 + strBuf.append(groups.toString());
2.109 + Log.get().info(strBuf.toString());
2.110
2.111 article.setGroup(groups.toString());
2.112 //article.removeHeader(Headers.REPLY_TO);
2.113 @@ -179,15 +180,15 @@
2.114 // Write article to database
2.115 if (updateReq) {
2.116 Log.get().info("Updating " + article.getMessageID()
2.117 - + " with additional groups");
2.118 + + " with additional groups");
2.119 StorageManager.current().delete(article.getMessageID());
2.120 StorageManager.current().addArticle(article);
2.121 } else {
2.122 Log.get().info("Gatewaying " + article.getMessageID() + " to "
2.123 - + article.getHeader(Headers.NEWSGROUPS)[0]);
2.124 + + article.getHeader(Headers.NEWSGROUPS)[0]);
2.125 StorageManager.current().addArticle(article);
2.126 Stats.getInstance().mailGatewayed(
2.127 - article.getHeader(Headers.NEWSGROUPS)[0]);
2.128 + article.getHeader(Headers.NEWSGROUPS)[0]);
2.129 }
2.130 posted = true;
2.131 } else {
2.132 @@ -196,12 +197,13 @@
2.133 buf.append(' ');
2.134 buf.append(toa.toString());
2.135 }
2.136 - buf.append(" " + article.getHeader(Headers.LIST_POST)[0]);
2.137 + buf.append(" ");
2.138 + buf.append(article.getHeader(Headers.LIST_POST)[0]);
2.139 Log.get().warning("No group for" + buf.toString());
2.140 }
2.141 return posted;
2.142 } catch (Exception ex) {
2.143 - ex.printStackTrace();
2.144 + Log.get().log(Level.WARNING, ex.getLocalizedMessage(), ex);
2.145 return false;
2.146 }
2.147 }
2.148 @@ -211,15 +213,17 @@
2.149 * This method MAY be called several times by PostCommand for the same
2.150 * article.
2.151 */
2.152 - public static void toList(Article article, String group)
2.153 - throws IOException, MessagingException, StorageBackendException
2.154 - {
2.155 + public static boolean toList(Article article, String group)
2.156 + throws IOException, MessagingException, StorageBackendException {
2.157 // Get mailing lists for the group of this article
2.158 List<String> rcptAddresses = StorageManager.current().getListsForGroup(group);
2.159
2.160 - if (rcptAddresses == null || rcptAddresses.size() == 0) {
2.161 - Log.get().warning("No ML-address for " + group + " found.");
2.162 - return;
2.163 + if (rcptAddresses == null || rcptAddresses.isEmpty()) {
2.164 + StringBuilder strBuf = new StringBuilder();
2.165 + strBuf.append("No ML address found for group ");
2.166 + strBuf.append(group);
2.167 + Log.get().warning(strBuf.toString());
2.168 + return false;
2.169 }
2.170
2.171 for (String rcptAddress : rcptAddresses) {
2.172 @@ -229,7 +233,7 @@
2.173 String smtpUser = Config.inst().get(Config.MLSEND_USER, "user");
2.174 String smtpPw = Config.inst().get(Config.MLSEND_PASSWORD, "mysecret");
2.175 String smtpFrom = Config.inst().get(
2.176 - Config.MLSEND_ADDRESS, article.getHeader(Headers.FROM)[0]);
2.177 + Config.MLSEND_ADDRESS, article.getHeader(Headers.FROM)[0]);
2.178
2.179 // TODO: Make Article cloneable()
2.180 article.getMessageID(); // Make sure an ID is existing
2.181 @@ -251,8 +255,9 @@
2.182
2.183 Stats.getInstance().mailGatewayed(group);
2.184 Log.get().info("MLGateway: Mail " + article.getHeader("Subject")[0]
2.185 - + " was delivered to " + rcptAddress + ".");
2.186 + + " was delivered to " + rcptAddress + ".");
2.187 }
2.188 + return true;
2.189 }
2.190
2.191 /**
2.192 @@ -262,8 +267,7 @@
2.193 * @throws javax.mail.MessagingException
2.194 */
2.195 private static void rewriteSenderAddress(Article msg)
2.196 - throws MessagingException
2.197 - {
2.198 + throws MessagingException {
2.199 String mlAddress = Config.inst().get(Config.MLSEND_ADDRESS, null);
2.200
2.201 if (mlAddress != null) {
3.1 --- a/src/org/sonews/storage/impl/JDBCDatabase.java Sun Sep 11 17:01:19 2011 +0200
3.2 +++ b/src/org/sonews/storage/impl/JDBCDatabase.java Sun Sep 11 17:36:47 2011 +0200
3.3 @@ -49,10 +49,9 @@
3.4 * @since sonews/0.5.0
3.5 */
3.6 // TODO: Refactor this class to reduce size (e.g. ArticleDatabase GroupDatabase)
3.7 -public class JDBCDatabase implements Storage
3.8 -{
3.9 +public class JDBCDatabase implements Storage {
3.10 + public static final int MAX_RESTARTS = 2;
3.11
3.12 - public static final int MAX_RESTARTS = 2;
3.13 protected Connection conn = null;
3.14 protected PreparedStatement pstmtAddArticle1 = null;
3.15 protected PreparedStatement pstmtAddArticle2 = null;