Ошибка подключения к почте при обращении несколько раз

webdriver
selenium
java
Теги: #<Tag:0x00007f7b64b29df0> #<Tag:0x00007f7b64b29cb0> #<Tag:0x00007f7b64b29b70>

(Влада Нижельская) #1

У меня в тестах несколько раз идет подключение к gmail:

  1. как клиент я делаю заказ и потом идет подключение к почте, чтобы вытащить номер заказа и сохраняю его в переменную.
  2. потом я захожу в заказ, используя переменную, и пишу сообщение как менеджер
  3. подключаюсь к почте, чтобы как клиент ответить на письмо.

В этом случае при попытке ответить на письмо у меня выдает ошибку com.sun.mail.util.MailConnectException: Couldn’t connect to host.

Если из теста исключить подключение к gmail чтобы вытащить номер заказа из письма то все ок


(Vatslau) #2

com.sun.mail.util.MailConnectException: Couldn’t connect to host.
каждый раз или иногда?
подключение к разным ящиками?
клиент статический?
клиент использется каждый раз новый?


(Влада Нижельская) #3

Один и тот же ящик, постоянно


(Влада Нижельская) #4

Вот я достаю из почты номер заказа

import javax.mail.*;
import javax.mail.search.SubjectTerm;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Properties;

public class MailOrderNum{
    public static String orderNum;

    public Message getEmail(String emailID, String password, String subjectToBeSearched) throws Exception {

        Properties properties = new Properties();
        properties.put("mail.store.protocol", "imaps");
        properties.put("mail.imaps.port", "993");
        properties.put("mail.imaps.starttls.enable", "true");

        Session emailSession = Session.getDefaultInstance(properties);

        Store store = emailSession.getStore("imaps");
        store.connect("imap.gmail.com", emailID, password);

        Folder folder = store.getFolder("INBOX");
        folder.open(Folder.READ_ONLY);

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        Message[] messages = null;
        boolean mailFound = false;
        Message email = null;

        for (int i = 0; i < 30; i++) {
            messages = folder.search(new SubjectTerm(subjectToBeSearched), folder.getMessages());

            if (messages.length == 0) {
                Thread.sleep(10000);
            }
        }

        for (Message mail : messages) {
            if (!mail.isSet(Flags.Flag.SEEN)) {
                email = mail;
                mailFound = true;
                System.out.println("Mail is found");
            }
        }

        String subject = email.getSubject();
        if (subject != null) {
            System.out.println("Subject: " + subject);
        }

        orderNum = subject.replaceAll("[^0-9]", "");
        System.out.println(orderNum);
        store.close();


        if (!mailFound) {
            throw new Exception("Could not found Email");
        }
        return email;
    }
}

Я беру переменную orderNum, нахожу этот заказ и как менеджер и пишу письмо.

А вот код для ответа на письмо клиентом

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.search.FromTerm;
import javax.mail.search.SearchTerm;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Properties;

public class MailReplySenderDesign {

    public Message getEmail(String emailID, String password) throws Exception {

        Properties properties = new Properties();
        properties.put("mail.store.protocol", "imaps");
        properties.put("mail.imaps.port", "993");
        properties.put("mail.imaps.starttls.enable", "true");
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.starttls.enable", "true");
        properties.put("mail.smtp.host", "smtp.gmail.com");
        properties.put("mail.smtp.port", "25");
        Session emailSession = Session.getDefaultInstance(properties);

        Store store = emailSession.getStore("imaps");
        store.connect("imap.gmail.com", emailID, password);

        Folder folder = store.getFolder("INBOX");
        folder.open(Folder.READ_ONLY);

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        Message[] messages = null;
        boolean mailFound = false;
        Message email = null;

        for (int i = 0; i < 30; i++) {
            SearchTerm sender;
            sender = new FromTerm(new InternetAddress("99designs@psd2html.com"));
            messages = folder.search(sender, folder.getMessages());

            if (messages.length == 0) {
                Thread.sleep(10000);
            }
        }

        for (Message mail : messages) {
            if (!mail.isSet(Flags.Flag.SEEN)) {
                email = mail;
                mailFound = true;
                System.out.println("Mail is found");
            }
        }

        String replyTo = InternetAddress.toString(email.getReplyTo());
        if (replyTo != null) {
            System.out.println("Reply-to: " + replyTo);
        }
        String to = InternetAddress.toString(email.getRecipients(Message.RecipientType.TO));
        if (to != null) {
            System.out.println("To: " + to);
        }

        Message replyMessage = new MimeMessage(emailSession);
        replyMessage = (MimeMessage) email.reply(false);
        replyMessage.setFrom(new InternetAddress(to));
        replyMessage.setText("Reply from client to design using email");
        replyMessage.setReplyTo(email.getReplyTo());

        try {
            Transport t = emailSession.getTransport("smtp");
            t.connect("8800190921Aleksandrova", "8800190921Aleksandrova");
            t.sendMessage(replyMessage,
                    replyMessage.getAllRecipients());
        } finally {
            store.close();
        }
        System.out.println("message replied successfully ....");


        if (!mailFound) {
            throw new Exception("Could not found Email");
        }
        return email;
    }
}

И вот это в связке выдает ошибку


(Vatslau) #5

не вижу - папку закрываете?
типа inbox.close(true);
что-то типа такого можно попробовать
или более подробно обернуть

         inbox.close(true);
			store.close();
		} catch (Exception e) {
			e.getMessage();
		}


этот код 2 года назад работал - может будет полезно


(Влада Нижельская) #6

это не сработало, попробую просмотреть код, который вы кинули


(Michael Beider) #7

В своей практике я сталкивался с ситуацией когда environment закрыт firewall и порты для imaps, pop3 и smtp перекрыты. Я разработал методы работы с Gmail API и с их помощью читаю и посылаю сообщения.
Для этого нужно создать application в gmail account и получить StoredCredential client_secret json.
С их помощью я читаю сообщения в реальном времени.
https://developers.google.com/gmail/api/guides/
https://developers.google.com/gmail/api/quickstart/java

   /** Global instance of the Gmail query. */
private static String DELIVERED_TO_AND_SUBJECT_AND_UNREAD = "deliveredto:%s AND subject:%s AND is:unread";

/** Global instance of the Gmail query. */
private static String DELIVERED_TO_AND_SUBJECT = "deliveredto:%s AND subject:%s";

/** Global instance of the HTTP transport. */
private static HttpTransport HTTP_TRANSPORT;

/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

/** Application name. */
private static final String APPLICATION_NAME = "Gmail User Password Retraction";

/** Global instance of the CLIENT_ID. */
private static final String CLIENT_ID = "me";

/**
 * Build and return an authorized Gmail client service.
 * @return an authorized Gmail client service
 * @throws IOException
 */
public static Gmail getGmailService() throws IOException {
    Credential credential = authorize();
    return new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();
}

/**
 * List all Messages of the user's mailbox matching the query.
 *
 * @param service Authorized Gmail API instance.
 * @param userId User's email address. The special value "me" can be used to indicate the authenticated user.
 * @param query String used to filter the Messages listed.
 * @throws IOException
 */
public static List<Message> listMessagesMatchingQuery(Gmail service, String query) throws IOException {

	List<Message> messages = new ArrayList<Message>();
	long startTime = System.currentTimeMillis(); 
	long endTime = startTime + SeleniumFrameworkProperties.getMailTimeoutWaitInMillieconds();
	while (messages.isEmpty() && System.currentTimeMillis() < endTime) {
		ListMessagesResponse response = service.users().messages().list(CLIENT_ID).setQ(query).execute();
		while (response.getMessages() != null) {
			messages.addAll(response.getMessages());
			if (response.getNextPageToken() != null) {
				String pageToken = response.getNextPageToken();
				response = service.users().messages().list(CLIENT_ID).setQ(query).setPageToken(pageToken).execute();
			} else {
				break;
			}
		}
	}
	if(System.currentTimeMillis() > endTime)
		log.info("Message search procces interapted after '{}' milliseconds of timeout",SeleniumFrameworkProperties.getMailTimeoutWaitInMillieconds());
	return messages;
}

/**
 * Send an email from the user's mailbox to its recipient.
 *
 * @param service Authorized Gmail API instance.
 * @param userId User's email address. The special value "me" can be used to indicate the authenticated user.
 * @param emailContent Email to be sent.
 * @return The sent message
 * @throws MessagingException
 * @throws IOException
 */
public static Message sendMessage(MimeMessage emailContent) throws MessagingException, IOException {
	
	// Build a new authorized API client service.
	Gmail service = getGmailService();

	Message message = createMessageWithEmail(emailContent);
    message = service.users().messages().send(CLIENT_ID, message).execute();

    log.info("Message id: {}", message.getId());
    log.info("JSON {}", message.toPrettyString());
    return message;
}

/**
 * Create a message from an email.
 *
 * @param emailContent Email to be set to raw of message
 * @return a message containing a base64url encoded email
 * @throws IOException
 * @throws MessagingException
 */
public static Message createMessageWithEmail(MimeMessage emailContent) throws MessagingException, IOException {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    emailContent.writeTo(buffer);
    byte[] bytes = buffer.toByteArray();
    String encodedEmail = Base64.encodeBase64URLSafeString(bytes);
    Message message = new Message();
    message.setRaw(encodedEmail);
    return message;
}

(Maxim Andryushchenkov) #8

Так, погодите, вижу что вы используете gmail и задам может быть глупый вопрос: а вы вообще разрешили внутри настроек gmail подключение к почте сторонних приложений? По умолчанию они выключены и при попытке подключиться из кода gmail вам присылает письмо с уведомлением безопасности. Прямо из этого письма есть возможность отключить эту защиту.


(Влада Нижельская) #9

Да, все разрешено


(Влада Нижельская) #10

Причем если отдельно запускать тесты, без связки, то все работает. Как только добавляется связка парсера номера заказа с почты и затем уже отправка туда сообщений и ответ клиента на них - все, ошибка соединения