You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@jakarta.apache.org by se...@apache.org on 2010/07/01 16:34:35 UTC
svn commit: r959681 [2/2] - in /jakarta/jmeter/trunk:
docs/images/screenshots/ src/core/org/apache/jmeter/resources/
src/protocol/mail/org/apache/jmeter/protocol/smtp/
src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/
src/protocol/mail/org/apa...
Added: jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/SendMailCommand.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/SendMailCommand.java?rev=959681&view=auto
==============================================================================
--- jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/SendMailCommand.java (added)
+++ jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/SendMailCommand.java Thu Jul 1 14:34:35 2010
@@ -0,0 +1,767 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.jmeter.protocol.smtp.sampler.protocol;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.security.Security;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Vector;
+
+import javax.activation.DataHandler;
+import javax.activation.FileDataSource;
+import javax.mail.BodyPart;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import org.apache.jmeter.services.FileServer;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.log.Logger;
+
+/**
+ * This class performs all tasks necessary to send a message (build message,
+ * prepare connection, send message). Provides getter-/setter-methods for an
+ * SmtpSampler-object to configure transport and message settings. The
+ * send-mail-command itself is started by the SmtpSampler-object.
+ */
+public class SendMailCommand {
+
+ /**
+ * Standard-Constructor
+ */
+ public SendMailCommand() {
+ headers = new HashMap<String, String>();
+ attachments = new Vector<File>();
+ }
+
+ // local vars
+ private static final Logger logger = LoggingManager.getLoggerForClass();
+ public static final String TRUST_ALL_SOCKET_FACTORY = "jmeter.smtpsampler.protocol.TrustAllSSLSocketFactory";
+
+ private boolean useSSL = false;
+ private boolean useStartTLS = false;
+ private boolean trustAllCerts = false;
+ private boolean enforceStartTLS = false;
+ private boolean startTLSSuccessful = false;
+ private boolean sendEmlMessage = false;
+ private String smtpServer;
+ private String smtpPort;
+ private String sender;
+ private String emlMessage;
+ private List<InternetAddress> receiverTo;
+ private List<InternetAddress> receiverCC;
+ private List<InternetAddress> receiverBCC;
+ private HashMap<String, String> headers;
+ private String subject = "";
+
+ private boolean useAuthentication = false;
+ private String username;
+ private String password;
+
+ private boolean useLocalTrustStore;
+ private String trustStoreToUse;
+
+ private List<File> attachments;
+
+ private MailBodyProvider mbProvider;
+
+ // needed to check starttls functionality
+ private PrintStream debugOutStream;
+ private BufferedReader debugReader;
+
+ // case we are measuring real time of spedition
+ private boolean synchronousMode;
+
+ private Session session;
+ private Message message;
+
+ private StringBuffer serverResponse = new StringBuffer();
+
+ /**
+ * Prepares message prior to be sent via execute()-method, i.e. sets
+ * properties such as protocol, authentication, etc.
+ *
+ * @return Message-object to be sent to execute()-method
+ * @throws MessagingException
+ * @throws IOException
+ */
+ public Message prepareMessage() throws MessagingException, IOException {
+
+ java.util.Properties props = new java.util.Properties();
+
+ String protocol = getProtocol();
+
+ // set properties using JAF
+ props.put("mail." + protocol + ".host", smtpServer);
+ props.put("mail." + protocol + ".port", smtpPort);
+ props.put("mail." + protocol + ".auth", Boolean
+ .toString(useAuthentication));
+ // props.put("mail.debug","true");
+
+ if (useStartTLS) {
+ props.put("mail.smtp.starttls.enable", "true");
+ //props.put("mail.debug", "true");
+ }
+
+ if (trustAllCerts && protocol.equalsIgnoreCase("smtps")) {
+ props.setProperty("mail.smtps.socketFactory.class",
+ TRUST_ALL_SOCKET_FACTORY);
+ props.setProperty("mail.smtps.socketFactory.fallback", "false");
+ }
+
+ session = Session.getInstance(props, null);
+
+ if (sendEmlMessage) {
+ message = new MimeMessage(session, new FileInputStream(emlMessage));
+ } else {
+ message = new MimeMessage(session);
+ // handle body and attachments
+ Multipart multipart = new MimeMultipart();
+ BodyPart body = new MimeBodyPart();
+ body.setText(mbProvider.getMailBody());
+ multipart.addBodyPart(body);
+
+ for (File f : attachments) {
+ BodyPart attach = new MimeBodyPart();
+ attach.setFileName(f.getName());
+ attach.setDataHandler(new DataHandler(new FileDataSource(f)));
+ multipart.addBodyPart(attach);
+ }
+
+ message.setContent(multipart);
+ }
+
+ // set from field and subject
+ if (null != sender) {
+ message.setFrom(new InternetAddress(sender));
+ }
+ if (null != subject) {
+ message.setSubject(subject);
+ }
+
+ if (receiverTo != null) {
+ InternetAddress[] to = new InternetAddress[receiverTo.size()];
+ receiverTo.toArray(to);
+ message.setRecipients(Message.RecipientType.TO, to);
+ }
+
+ if (receiverCC != null) {
+
+ InternetAddress[] cc = new InternetAddress[receiverCC.size()];
+ receiverCC.toArray(cc);
+ message.setRecipients(Message.RecipientType.CC, cc);
+ }
+
+ if (receiverBCC != null) {
+ InternetAddress[] bcc = new InternetAddress[receiverBCC.size()];
+ receiverBCC.toArray(bcc);
+ message.setRecipients(Message.RecipientType.BCC, bcc);
+ }
+
+ for (String key : headers.keySet()) {
+ message.setHeader(key, headers.get(key));
+ }
+
+ message.saveChanges();
+ return message;
+ }
+
+ /**
+ * Sends message to mailserver, including all necessary tasks. Contains 2
+ * ugly hacks to ensure the use of StartTLS if needed (see comments "UGLY
+ * HACK X") where logfiles are monitored
+ *
+ * @param message
+ * Message prior prepared by prepareMessage()
+ * @throws Exception
+ */
+ public void execute(Message message) throws Exception {
+
+ System.clearProperty("javax.net.ssl.trustStore");
+
+ if (useLocalTrustStore) {
+ File truststore = new File(trustStoreToUse);
+ logger.info("load local truststore - try to load truststore from: "+truststore.getAbsolutePath());
+ if(!truststore.exists()){
+ logger.info("load local truststore -Failed to load truststore from: "+truststore.getAbsolutePath());
+ truststore = new File(FileServer.getFileServer().getBaseDir(), trustStoreToUse);
+ logger.info("load local truststore -Attempting to read truststore from: "+truststore.getAbsolutePath());
+ if(!truststore.exists()){
+ logger.info("load local truststore -Failed to load truststore from: "+truststore.getAbsolutePath() + ". Local truststore not available, aborting execution.");
+ throw new IOException("Local truststore file not found. Also not available under : " + truststore.getAbsolutePath());
+ }
+ }
+ System.setProperty("javax.net.ssl.trustStore", truststore.getAbsolutePath());
+ }
+
+ /*
+ * UGLY HACK 1: redirect session-DebugOutput to ensure
+ * StartTLS-Support
+ */
+ ByteArrayOutputStream debugOutputStream = new ByteArrayOutputStream();
+ debugOutStream = new PrintStream(debugOutputStream);
+ session.setDebugOut(debugOutStream);
+ session.setDebug(true);
+
+ Transport tr = session.getTransport(getProtocol());
+ SynchronousTransportListener listener = null;
+
+ if (synchronousMode) {
+ listener = new SynchronousTransportListener();
+ tr.addTransportListener(listener);
+ }
+
+ if (useAuthentication) {
+ tr.connect(smtpServer, username, password);
+ } else {
+ tr.connect();
+ }
+
+ tr.sendMessage(message, message.getAllRecipients());
+
+ if (synchronousMode) {
+ listener.attend();
+ }
+
+ tr.close();
+ logger.debug("transport closed");
+
+ /*
+ * UGLY HACK 2: read from redirected debug-output
+ */
+ debugOutStream.flush();
+ debugReader = new BufferedReader(new InputStreamReader(
+ new ByteArrayInputStream(debugOutputStream.toByteArray())));
+ String line;
+ int i = 0;
+ while ((line = debugReader.readLine()) != null) {
+ logger.debug("server line " + i + ": " + line);
+ // unusable for the astf runs bom
+ //serverResponse.append(line);
+ //serverResponse.append("\n");
+ if (line.matches(".*Ready to start TLS.*")) {
+ if (useStartTLS && enforceStartTLS) {
+ startTLSSuccessful = true;
+ }
+ }
+ }
+ debugReader.close();
+ debugOutStream.close();
+ session.setDebugOut(System.out);
+ if (useStartTLS && enforceStartTLS) {
+ if (!startTLSSuccessful) {
+ throw new MessagingException("StartTLS failed");
+ }
+ }
+
+ logger.debug("message sent");
+ return;
+ }
+
+ /**
+ * Processes prepareMessage() and execute()
+ *
+ * @throws Exception
+ */
+ public void execute() throws Exception {
+ execute(prepareMessage());
+ }
+
+ /**
+ * Returns FQDN or IP of SMTP-server to be used to send message - standard
+ * getter
+ *
+ * @return FQDN or IP of SMTP-server
+ */
+ public String getSmtpServer() {
+ return smtpServer;
+ }
+
+ /**
+ * Sets FQDN or IP of SMTP-server to be used to send message - to be called
+ * by SmtpSampler-object
+ *
+ * @param smtpServer
+ * FQDN or IP of SMTP-server
+ */
+ public void setSmtpServer(String smtpServer) {
+ this.smtpServer = smtpServer;
+ }
+
+ /**
+ * Returns sender-address for current message - standard getter
+ *
+ * @return sender-address
+ */
+ public String getSender() {
+ return sender;
+ }
+
+ /**
+ * Sets the sender-address for the current message - to be called by
+ * SmtpSampler-object
+ *
+ * @param sender
+ * Sender-address for current message
+ */
+ public void setSender(String sender) {
+ this.sender = sender;
+ }
+
+ /**
+ * Returns subject for current message - standard getter
+ *
+ * @return Subject of current message
+ */
+ public String getSubject() {
+ return subject;
+ }
+
+ /**
+ * Sets subject for current message - called by SmtpSampler-object
+ *
+ * @param subject
+ * Subject for message of current message
+ */
+ public void setSubject(String subject) {
+ this.subject = subject;
+ }
+
+ /**
+ * Returns MailBodyProvider-Object for currend message
+ *
+ * @see MailBodyProvider
+ * @return Current MailBody-Provider-Object
+ */
+ public MailBodyProvider getMbProvider() {
+ return mbProvider;
+ }
+
+ /**
+ * Sets MailBodyProvider-Object for currend message - to be called by
+ * SmtpSampler-object
+ *
+ * @see MailBodyProvider
+ * @param mbProvider
+ * MailBody-Provider to be used
+ */
+ public void setMbProvider(MailBodyProvider mbProvider) {
+ this.mbProvider = mbProvider;
+ }
+
+ /**
+ * Returns username to authenticate at the mailserver - standard getter
+ *
+ * @return Username for mailserver
+ */
+ public String getUsername() {
+ return username;
+ }
+
+ /**
+ * Sets username to authenticate at the mailserver - to be called by
+ * SmtpSampler-object
+ *
+ * @param username
+ * Username for mailserver
+ */
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ /**
+ * Returns password to authenticate at the mailserver - standard getter
+ *
+ * @return Password for mailserver
+ */
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+ * Sets password to authenticate at the mailserver - to be called by
+ * SmtpSampler-object
+ *
+ * @param password
+ * Password for mailserver
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ /**
+ * Returns receivers of current message <InternetAddress> ("to") - standard
+ * getter
+ *
+ * @return List of receivers
+ */
+ public List<InternetAddress> getReceiverTo() {
+ return receiverTo;
+ }
+
+ /**
+ * Sets receivers of current message ("to") - to be called by
+ * SmtpSampler-object
+ *
+ * @param receiverTo
+ * List of receivers <InternetAddress>
+ */
+ public void setReceiverTo(List<InternetAddress> receiverTo) {
+ this.receiverTo = receiverTo;
+ }
+
+ /**
+ * Returns receivers of current message <InternetAddress> ("cc") - standard
+ * getter
+ *
+ * @return List of receivers
+ */
+ public List<InternetAddress> getReceiverCC() {
+ return receiverCC;
+ }
+
+ /**
+ * Sets receivers of current message ("cc") - to be called by
+ * SmtpSampler-object
+ *
+ * @param receiverCC
+ * List of receivers <InternetAddress>
+ */
+ public void setReceiverCC(List<InternetAddress> receiverCC) {
+ this.receiverCC = receiverCC;
+ }
+
+ /**
+ * Returns receivers of current message <InternetAddress> ("bcc") - standard
+ * getter
+ *
+ * @return List of receivers
+ */
+ public List<InternetAddress> getReceiverBCC() {
+ return receiverBCC;
+ }
+
+ /**
+ * Sets receivers of current message ("bcc") - to be called by
+ * SmtpSampler-object
+ *
+ * @param receiverBCC
+ * List of receivers <InternetAddress>
+ */
+ public void setReceiverBCC(List<InternetAddress> receiverBCC) {
+ this.receiverBCC = receiverBCC;
+ }
+
+ /**
+ * Returns if authentication is used to access the mailserver - standard
+ * getter
+ *
+ * @return True if authentication is used to access mailserver
+ */
+ public boolean isUseAuthentication() {
+ return useAuthentication;
+ }
+
+ /**
+ * Sets if authentication should be used to access the mailserver - to be
+ * called by SmtpSampler-object
+ *
+ * @param useAuthentication
+ * Should authentication be used to access mailserver?
+ */
+ public void setUseAuthentication(boolean useAuthentication) {
+ this.useAuthentication = useAuthentication;
+ }
+
+ /**
+ * Returns if SSL is used to send message - standard getter
+ *
+ * @return True if SSL is used to transmit message
+ */
+ public boolean getUseSSL() {
+ return useSSL;
+ }
+
+ /**
+ * Sets SSL to secure the delivery channel for the message - to be called by
+ * SmtpSampler-object
+ *
+ * @param useSSL
+ * Should StartTLS be used to secure SMTP-connection?
+ */
+ public void setUseSSL(boolean useSSL) {
+ this.useSSL = useSSL;
+ }
+
+ /**
+ * Returns if StartTLS is used to transmit message - standard getter
+ *
+ * @return True if StartTLS is used to transmit message
+ */
+ public boolean getUseStartTLS() {
+ return useStartTLS;
+ }
+
+ /**
+ * Sets StartTLS to secure the delivery channel for the message - to be
+ * called by SmtpSampler-object
+ *
+ * @param useStartTLS
+ * Should StartTLS be used to secure SMTP-connection?
+ */
+ public void setUseStartTLS(boolean useStartTLS) {
+ this.useStartTLS = useStartTLS;
+ }
+
+ /**
+ * Returns port to be used for SMTP-connection (standard 25 or 465) -
+ * standard getter
+ *
+ * @return Port to be used for SMTP-connection
+ */
+ public String getSmtpPort() {
+ return smtpPort;
+ }
+
+ /**
+ * Sets port to be used for SMTP-connection (standard 25 or 465) - to be
+ * called by SmtpSampler-object
+ *
+ * @param smtpPort
+ * Port to be used for SMTP-connection
+ */
+ public void setSmtpPort(String smtpPort) {
+ this.smtpPort = smtpPort;
+ }
+
+ /**
+ * Returns if sampler should trust all certificates - standard getter
+ *
+ * @return True if all Certificates are trusted
+ */
+ public boolean isTrustAllCerts() {
+ return trustAllCerts;
+ }
+
+ /**
+ * Determines if SMTP-sampler should trust all certificates, no matter what
+ * CA - to be called by SmtpSampler-object
+ *
+ * @param trustAllCerts
+ * Should all certificates be trusted?
+ */
+ public void setTrustAllCerts(boolean trustAllCerts) {
+ if (useSSL) {
+ if (trustAllCerts) {
+ Security.setProperty("ssl.SocketFactory.provider",
+ TRUST_ALL_SOCKET_FACTORY);
+ } else {
+ Security.setProperty("ssl.SocketFactory.provider", "");
+ }
+ }
+ this.trustAllCerts = trustAllCerts;
+ }
+
+ /**
+ * Instructs object to enforce StartTLS and not to fallback to plain
+ * SMTP-connection - to be called by SmtpSampler-object
+ *
+ * @param enforceStartTLS
+ * Should StartTLS be enforced?
+ */
+ public void setEnforceStartTLS(boolean enforceStartTLS) {
+ this.enforceStartTLS = enforceStartTLS;
+ }
+
+ /**
+ * Returns if StartTLS is enforced to secure the connection, i.e. no
+ * fallback is used (plain SMTP) - standard getter
+ *
+ * @return True if StartTLS is enforced
+ */
+ public boolean isEnforceStartTLS() {
+ return enforceStartTLS;
+ }
+
+ /**
+ * Returns headers for current message - standard getter
+ *
+ * @return HashMap of headers for current message
+ */
+ public HashMap<String, String> getHeaders() {
+ return headers;
+ }
+
+ /**
+ * Sets headers for current message
+ *
+ * @param headers
+ * HashMap of headers for current message
+ */
+ public void setHeaders(HashMap<String, String> headers) {
+ this.headers = headers;
+ }
+
+ /**
+ * Adds a header-part to current HashMap of headers - to be called by
+ * SmtpSampler-object
+ *
+ * @param headerName
+ * Key for current header
+ * @param headerValue
+ * Value for current header
+ */
+ public void addHeader(String headerName, String headerValue) {
+ if (this.headers == null)
+ this.headers = new HashMap<String, String>();
+ this.headers.put(headerName, headerValue);
+ }
+
+ /**
+ * Deletes all current headers in HashMap
+ */
+ public void clearHeaders() {
+ if (this.headers == null)
+ this.headers = new HashMap<String, String>();
+ else
+ this.headers.clear();
+ }
+
+ /**
+ * Returns all attachment for current message - standard getter
+ *
+ * @return List of attachments for current message
+ */
+ public List<File> getAttachments() {
+ return attachments;
+ }
+
+ /**
+ * Adds attachments to current message
+ *
+ * @param attachments
+ * List of files to be added as attachments to current message
+ */
+ public void setAttachments(List<File> attachments) {
+ this.attachments = attachments;
+ }
+
+ /**
+ * Adds an attachment to current message - to be called by
+ * SmtpSampler-object
+ *
+ * @param attachment
+ * File-object to be added as attachment to current message
+ */
+ public void addAttachment(File attachment) {
+ this.attachments.add(attachment);
+ }
+
+ /**
+ * Clear all attachments for current message
+ */
+ public void clearAttachments() {
+ this.attachments.clear();
+ }
+
+ /**
+ * Returns if synchronous-mode is used for current message (i.e. time for
+ * delivery, ... is measured) - standard getter
+ *
+ * @return True if synchronous-mode is used
+ */
+ public boolean isSynchronousMode() {
+ return synchronousMode;
+ }
+
+ /**
+ * Sets the use of synchronous-mode (i.e. time for delivery, ... is
+ * measured) - to be called by SmtpSampler-object
+ *
+ * @param synchronousMode
+ * Should synchronous-mode be used?
+ */
+ public void setSynchronousMode(boolean synchronousMode) {
+ this.synchronousMode = synchronousMode;
+ }
+
+ /**
+ * Returns which protocol should be used to transport message (smtps for
+ * SSL-secured connections or smtp for plain SMTP / StartTLS)
+ *
+ * @return Protocol that is used to transport message
+ */
+ private String getProtocol() {
+ return (useSSL) ? "smtps" : "smtp";
+ }
+
+ /**
+ * Assigns the object to use a local truststore for SSL / StartTLS - to be
+ * called by SmtpSampler-object
+ *
+ * @param useLocalTrustStore
+ * Should a local truststore be used?
+ */
+ public void setUseLocalTrustStore(boolean useLocalTrustStore) {
+ this.useLocalTrustStore = useLocalTrustStore;
+ }
+
+ /**
+ * Sets the path to the local truststore to be used for SSL / StartTLS - to
+ * be called by SmtpSampler-object
+ *
+ * @param trustStoreToUse
+ * Path to local truststore
+ */
+ public void setTrustStoreToUse(String trustStoreToUse) {
+ this.trustStoreToUse = trustStoreToUse;
+ }
+
+ public void setUseEmlMessage(boolean sendEmlMessage) {
+ this.sendEmlMessage = sendEmlMessage;
+ }
+
+ /**
+ * Sets eml-message to be sent
+ *
+ * @param emlMessage
+ * path to eml-message
+ */
+ public void setEmlMessage(String emlMessage) {
+ this.emlMessage = emlMessage;
+ }
+
+ public StringBuffer getServerResponse() {
+ return this.serverResponse;
+ }
+}
\ No newline at end of file
Propchange: jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/SendMailCommand.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/SendMailCommand.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/SynchronousTransportListener.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/SynchronousTransportListener.java?rev=959681&view=auto
==============================================================================
--- jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/SynchronousTransportListener.java (added)
+++ jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/SynchronousTransportListener.java Thu Jul 1 14:34:35 2010
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.jmeter.protocol.smtp.sampler.protocol;
+
+import javax.mail.event.TransportAdapter;
+import javax.mail.event.TransportEvent;
+import org.apache.jorphan.logging.LoggingManager;
+import org.apache.log.Logger; // this comes out of logkit.jar and not
+
+// commons-logger
+
+/**
+ * This class implements a listener for SMTP events and a monitor for all
+ * threads sending mail. The main purpose is to synchronize the send action with
+ * the end of communication with remote smtp server, so that sending time can be
+ * measured.
+ */
+public class SynchronousTransportListener extends TransportAdapter {
+
+ private static final Logger logger = LoggingManager.getLoggerForClass();
+
+ private boolean finished = false;
+
+ /**
+ * Creates a new instance of SynchronousTransportListener
+ */
+ public SynchronousTransportListener() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void messageDelivered(TransportEvent e) {
+ logger.debug("Message delivered");
+ finish();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void messageNotDelivered(TransportEvent e) {
+ logger.debug("Message not delivered");
+ finish();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void messagePartiallyDelivered(TransportEvent e) {
+ logger.debug("Message partially delivered");
+ finish();
+ }
+
+ /**
+ * Synchronized-method
+ *
+ * @throws InterruptedException
+ */
+ public synchronized void attend() throws InterruptedException {
+ if (!finished)
+ wait();
+ }
+
+ /**
+ * Synchronized-method
+ */
+ public synchronized void finish() {
+ finished = true;
+ notify();
+ }
+
+}
Propchange: jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/SynchronousTransportListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/SynchronousTransportListener.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/TrustAllSSLSocketFactory.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/TrustAllSSLSocketFactory.java?rev=959681&view=auto
==============================================================================
--- jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/TrustAllSSLSocketFactory.java (added)
+++ jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/TrustAllSSLSocketFactory.java Thu Jul 1 14:34:35 2010
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.jmeter.protocol.smtp.sampler.protocol;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * This class can be used as a SocketFactory with SSL-connections.
+ * Its purpose is to ensure that all certificates - no matter from which CA -are accepted to secure the SSL-connection.
+ * It has to be kept in mind that a SocketFactory must not be used with StartTLS, because the javaMail-api assumes
+ * to use SSL when using the socketFactory.class- or socketFactory.fallback-property.
+ *
+ */
+public class TrustAllSSLSocketFactory extends SSLSocketFactory {
+
+ private final SSLSocketFactory factory;
+
+ /**
+ * Standard constructor
+ */
+ public TrustAllSSLSocketFactory(){
+ SSLContext sslcontext = null;
+ try {
+ sslcontext = SSLContext.getInstance( "TLS");
+ sslcontext.init( null, new TrustManager[]{
+ new X509TrustManager() {
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+ }
+ },
+ new java.security.SecureRandom());
+ } catch (Exception e) {
+ throw new RuntimeException("Could not create the SSL context",e);
+ }
+ factory = sslcontext.getSocketFactory();
+ }
+
+ /**
+ * Factory method
+ * @return New TrustAllSSLSocketFactory
+ */
+ public static SocketFactory getDefault() {
+ return new TrustAllSSLSocketFactory();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Socket createSocket( Socket socket, String s, int i, boolean
+ flag)
+ throws IOException {
+ return factory.createSocket( socket, s, i, flag);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Socket createSocket( InetAddress inaddr, int i,
+ InetAddress inaddr1, int j) throws IOException {
+ return factory.createSocket( inaddr, i, inaddr1, j);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Socket createSocket( InetAddress inaddr, int i) throws
+ IOException {
+ return factory.createSocket( inaddr, i);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Socket createSocket( String s, int i, InetAddress inaddr, int j)
+ throws IOException {
+ return factory.createSocket( s, i, inaddr, j);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Socket createSocket( String s, int i) throws IOException {
+ return factory.createSocket( s, i);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Socket createSocket() throws IOException {
+ return factory.createSocket();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String[] getDefaultCipherSuites() {
+ return factory.getSupportedCipherSuites();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String[] getSupportedCipherSuites() {
+ return factory.getSupportedCipherSuites();
+ }
+}
\ No newline at end of file
Propchange: jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/TrustAllSSLSocketFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/protocol/TrustAllSSLSocketFactory.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/tools/CounterOutputStream.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/tools/CounterOutputStream.java?rev=959681&view=auto
==============================================================================
--- jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/tools/CounterOutputStream.java (added)
+++ jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/tools/CounterOutputStream.java Thu Jul 1 14:34:35 2010
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.jmeter.protocol.smtp.sampler.tools;
+
+import java.io.OutputStream;
+
+/**
+ * Utility-class to calculate message size.
+ */
+public class CounterOutputStream extends OutputStream {
+ int count = 0;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+
+ public void close() {}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void flush() {}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void write(byte[] b, int off, int len) {
+ count += len;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void write(int b) {
+ count++;
+ }
+
+ /**
+ * Returns message size
+ * @return Message size
+ */
+ public int getCount() {
+ return count;
+ }
+}
Propchange: jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/tools/CounterOutputStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/jmeter/trunk/src/protocol/mail/org/apache/jmeter/protocol/smtp/sampler/tools/CounterOutputStream.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: jakarta/jmeter/trunk/xdocs/images/screenshots/smtp_sampler.png
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/images/screenshots/smtp_sampler.png?rev=959681&view=auto
==============================================================================
Binary file - no diff available.
Propchange: jakarta/jmeter/trunk/xdocs/images/screenshots/smtp_sampler.png
------------------------------------------------------------------------------
svn:mime-type = image/png
Modified: jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=959681&r1=959680&r2=959681&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
+++ jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml Thu Jul 1 14:34:35 2010
@@ -1484,7 +1484,54 @@ In non-GUI mode, JMeter will exit if som
<property name="Action" required="Yes">Pause / Stop / Stop Now</property>
<property name="Duration" required="Yes, if Pause is selected">How long to pause for (milliseconds)</property>
</properties>
-</component><a href="#">^</a>
+</component>
+
+
+<component name="SMTP Sampler" index="§-num;.1.19" width="644" height="801" screenshot="smtp_sampler.png">
+<note>
+BETA code. This sampler currently uses System properties to control some aspects of its behaviour.
+There are likely to be problems when using more than one thread with multiple samplers that have different settings;
+and the sampler may interfere with other samplers that use SSL.
+</note>
+<description>
+<p>
+The SMTP Sampler can send mail messages using SMTP/SMTPS protocol.
+It is possible to set security propocols for the connection (SSL and TLS), as well as user authentication.
+If a security protocol is used a verification on the server certificate will occur. <br></br>
+Two alternatives to handle this verification are available:<br></br>
+<ul>
+<li>Trust all certificates. This will ignore certificate chain verification</li>
+<li>Use a local truststore. With this option the certificate chain will be validated against the local truststore file.</li>
+</ul>
+</p>
+</description>
+<properties>
+<property name="Server" required="Yes">Hostname or IP address of the server. See below for use with <code>file</code> protocol.</property>
+<property name="Port" required="Yes">Port to be used to connect to the server (optional)</property>
+<property name="Address From" required="Yes">The from address that will appear in the e-mail</property>
+<property name="Address To" required="Yes">The destination e-mail address</property>
+<property name="Address To BCC" required="No">Blind carbon copy destinations e-mail address</property>
+<property name="Address To CC" required="No">Carbon copy destinations e-mail address</property>
+<property name="Use Auth" required="">Indicates if the SMTP server requires user authentication</property>
+<property name="Username" required="">User login name</property>
+<property name="Password" required="">User login password (N.B. this is stored unencrypted in the test plan)</property>
+<property name="Use no security features" required="">Indicates that the connection to the SMTP server does not use any security protocol.</property>
+<property name="Use SSL" required="">Indicates that the connection to the SMTP server must use the SSL protocol.</property>
+<property name="Use StartTLS" required="">Indicates that the connection to the SMTP server should attempt to start the TLS protocol.</property>
+<property name="Enforce StartTLS" required="">If the server does not start the TLS protocol the connection will be terminated.</property>
+<property name="Trust All Certificates" required="">When selected it will accept all certificates independent of the CA.</property>
+<property name="Use local truststore" required="">When selected it will only accept certificates that are locally trusted.</property>
+<property name="Local truststore" required="">Local file containing the trusted certificates.</property>
+<property name="Subject" required="">The e-mail message subject.</property>
+<property name="Include timestamp in subject" required="">Includes the System.currentTimemilis() in the subject line.</property>
+<property name="Message" required="">The message body.</property>
+<property name="Attach files" required="">Files to be attached to the message.</property>
+<property name="Send .eml" required="">If set, the .eml file will be sent instead of the entries in the Subject, Message, and Attached files</property>
+<property name="Calculate message size" required="">Calculates the message size and stores it in the sample result.</property>
+</properties>
+</component>
+
+<a href="#">^</a>
</section>
@@ -3669,20 +3716,25 @@ The assertion comparisons can be seen in
</properties>
</component>
-<component name="SMIME Assertion" index="§-num;.5.13" width="473" height="370" screenshot="assertion/smime.png">
+<component name="SMIME Assertion" index="§-num;.5.13" width="471" height="428" screenshot="assertion/smime.png">
<description>
The SMIME Assertion can be used to evaluate the sample results from the Mail Reader Sampler.
This assertion verifies if the body of a mime message is signed or not. The signature can also be verified against a specific signer certificate.
As this is a functionality that is not necessarily needed by most users, additional jars need to be downloaded and added to JMETER_HOME/lib :<br></br>
<ul>
-<li>bcmail-jdk15-145.jar</li>
-<li>bcprov-jdk15-145.jar</li>
+<li>bcmail-xxx.jar (BouncyCastle SMIME/CMS)</li>
+<li>bcprov-xxx.jar (BouncyCastle Provider)</li>
</ul>
+These need to be <a href="http://www.bouncycastle.org/latest_releases.html">downloaded from BouncyCastle.</a>
+<p>
+If using the <complink name="Mail Reader Sampler">Mail Reader Sampler</complink>,
+please ensure that you select "Store the message using MIME (raw)" otherwise the Assertion won't be able to process the message correctly.
+</p>
</description>
<properties>
<property name="Name" required="No">Descriptive name for this element that is shown in the tree.</property>
- <property name="Message not signed" required="Yes">Whether or not to expect a signature in the message</property>
<property name="Verify Signature" required="Yes">If selected, the asertion will verify if it is a valid signature according to the parameters defined in the Signer Certificate box.</property>
+ <property name="Message not signed" required="Yes">Whether or not to expect a signature in the message</property>
<property name="Signer Cerificate" required="Yes">"No Check" means that it wil not perform signature verification. "Check values" is used to verify the signature against the inputs provided. And "Certificate file" will perform the verification against a specific certificate file.</property>
<property name="Message Position" required="Yes">
The Mail sampler can retrieve multiple messages in a single sample.
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@jakarta.apache.org
For additional commands, e-mail: notifications-help@jakarta.apache.org