xinyb
3 天以前 3b74e3df72726e188d36393ecfd7964d095ef7e8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
package com.yc.crm.schedule;
 
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore;
import com.yc.api.schedule.ScheduleUtils;
import com.yc.crm.mail.entity.FoundationEntity;
import com.yc.crm.mail.entity.T482102Entity;
import com.yc.crm.mail.service.MailAccountIfc;
import com.yc.crm.mail.service.MailServiceIfc;
import com.yc.entity.AttachmentConfig;
import com.yc.entity.DataSourceEntity;
import com.yc.factory.FactoryBean;
import com.yc.multiData.MultiDataSource;
import com.yc.multiData.SpObserver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;
 
import javax.mail.*;
import javax.mail.event.MessageCountEvent;
import javax.mail.event.MessageCountListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
 
/**
 * 实时监听邮箱
 */
@Slf4j
@Service
public class EmailSchedule implements ApplicationListener<ContextRefreshedEvent> {
    @Autowired
    ThreadPoolTaskExecutor threadPoolExecutor;
    @Autowired
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;
    @Autowired
    MailAccountIfc emailAccountIfc;
    @Autowired
    MailServiceIfc mailServiceIfc;
 
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        if (contextRefreshedEvent.getApplicationContext().getParent() == null) {
            return;
        }
        threadPoolTaskScheduler = (ThreadPoolTaskScheduler) FactoryBean.getBean("threadPoolTaskScheduler");
        threadPoolExecutor = (ThreadPoolTaskExecutor) FactoryBean.getBean("threadPoolExecutor");
        String isStartUpSchedule = AttachmentConfig.get("isStartUpSchedule");//只在设置了定时任务的服务器上运行
        if ("1".equals(isStartUpSchedule)) {
            Map<String, DataSourceEntity> infoList = MultiDataSource.getDataSourceMaps();
            for (Map.Entry<String, DataSourceEntity> entry : infoList.entrySet()) {
                DataSourceEntity dataSourceEntity = entry.getValue();
                if (ScheduleUtils.isOnbusPlatform(dataSourceEntity) || dataSourceEntity.getDbId() == 1624) {
                    //dbid=1624,巴士软件(佛山公司),不需要执行定时任务
                    continue;
                }
          // if (dataSourceEntity.getDbId() != 82) continue;//TODO 测试用
               emailTask(dataSourceEntity);
            }
        }
    }
 
    private void emailTask(DataSourceEntity dataSourceEntity) {
            try {
                SpObserver.setDBtoInstance("_" + dataSourceEntity.getDbId());
                List<T482102Entity> list = emailAccountIfc.getAccountList();
                log.info(dataSourceEntity.getDbId()+"-加载邮箱数量:"+list.size());
                for (T482102Entity t482102Entity : list) {
                        threadPoolExecutor.execute(new checkEmailThread(t482102Entity,dataSourceEntity));
                }
            } catch (Exception e) {
                System.out.println("取不到邮箱设置内容:dbid=" + dataSourceEntity.getDbId() + ":" + e.getMessage());
                e.printStackTrace();
            } finally {
                SpObserver.setDBtoInstance();
            }
        }
 
    private class checkEmailThread implements Runnable {
        T482102Entity emailEntity;
        FoundationEntity foundation;
        DataSourceEntity dataSourceEntity;
        public checkEmailThread(T482102Entity t482102Entity, DataSourceEntity dataSourceEntity) {
            this.emailEntity = t482102Entity;
            this.dataSourceEntity = dataSourceEntity;
            foundation=new FoundationEntity();
            foundation.setDbId(dataSourceEntity.getDbId());
            foundation.setCompanyName(emailEntity.getCompanyName());
            foundation.setCompanyId(emailEntity.getCompanyId());
            foundation.setUserCode(emailEntity.getUserCode());
            foundation.setUserName(emailEntity.getUserName());
        }
 
        @Override
        public void run() {
            checkEmail();
    }
    private void checkEmail() {
        try {
            String protocol = emailEntity.getReceiveProtocol().toLowerCase();//接收协议 imap pop3
            String server = emailEntity.getReceiveHost();//"imap.qq.com";
            Integer port = emailEntity.getReceivePort();//993
            String user =emailEntity.getReceiveEmail();//邮箱
            String pwd = emailEntity.getReceivePassword();//密码
            Properties properties = new Properties();
            properties.setProperty("mail.store.protocol", protocol); // IMAP over SSL
            if (protocol.contains("imap")) {//接收协议imap
                properties.setProperty("mail.imaps.host", server);
                properties.setProperty("mail.imaps.port", port + "");
            } else if (protocol.contains("pop3")) {//接收协议pop3
                properties.setProperty("mail.pop3.host", server);
                properties.setProperty("mail.pop3.port", port + "");
            } else {//其他(再加)
                properties.setProperty("mail.imaps.host", server);
                properties.setProperty("mail.imaps.port", port + "");
            }
            HashMap IAM = new HashMap();
            //带上IMAP ID信息,由key和value组成,例如name,version,vendor,support-email等。
            IAM.put("name", user);
            IAM.put("version", emailEntity.getDocVersion() + "");
            IAM.put("vendor", emailEntity.getCompanyName());
            IAM.put("support-email", emailEntity.getEmail());
            //创建会话
            Session session = Session.getInstance(properties, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(user, pwd);
                }
            });
            //存储对象
            IMAPStore store = (IMAPStore) session.getStore(protocol);//imap协议或pop3协议类型(推荐你使用IMAP协议来存取服务器上的邮件。)
            //连接
            store.connect(server, user, pwd);
            store.id(IAM);//163邮箱需要,不然会报:A3 NO SELECT Unsafe Login. Please contact kefu@188.com for help
            Folder folder = null;
            try {
                // 获得收件箱
                folder = store.getFolder("INBOX");
                // 以读写模式打开收件箱
                folder.open(Folder.READ_WRITE);
                log.info(emailEntity.getEmail() + "已就绪接收新邮件....");
                folder.addMessageCountListener(new MessageCountListener() {
                    @Override
                    public void messagesAdded(MessageCountEvent e) {
                        //TODO 处理新邮件
                        try {
                            SpObserver.setDBtoInstance("_" + dataSourceEntity.getDbId());
                            mailServiceIfc.setMailContent(e.getMessages(), emailEntity, foundation,true);
                        }catch (Exception e1){
                            e1.printStackTrace();
                        }finally {
                            SpObserver.setDBtoInstance();
                        }
                        log.info(emailEntity.getEmail()+":Message Count Event Fired");
                    }
                    @Override
                    public void messagesRemoved(MessageCountEvent e) {
                       // System.out.println(emailEntity.getEmail()+"Message Count Event Fired");
                    }
                });
 
               /* folder.addMessageChangedListener(new MessageChangedListener() {
                    @Override
                    public void messageChanged(MessageChangedEvent e) {
                        System.out.println(emailEntity.getEmail()+"Message Count Event Fired");
                    }
                });*/
                // Check mail once in "freq" MILLIseconds
                int freq = 2000;
                boolean supportsIdle = false;
                try {
                    if (folder instanceof IMAPFolder) {
                        IMAPFolder f = (IMAPFolder) folder;
                        f.idle();
                        supportsIdle = true;
                    }
                } catch (FolderClosedException fex) {
                    throw fex;
                } catch (MessagingException mex) {
                    supportsIdle = false;
                }
                for (; ; ) {
                    if (supportsIdle && folder instanceof IMAPFolder) {
                        IMAPFolder f = (IMAPFolder) folder;
                        f.idle();
                       // System.out.println(emailEntity.getEmail()+"IDLE done");
                    } else {
                        Thread.sleep(freq); // sleep for freq milliseconds
                        // This is to force the IMAP server to send us
                        // EXISTS notifications.
                        folder.getMessageCount();
                    }
                }
 
            } catch (FolderClosedException fe) {
                log.info("FolderClosedException......");
                checkEmail();
 
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                try {
                    if (folder != null) {
                        folder.close(false);
                    }
                    if (store != null) {
                        store.close();
                    }
                } catch (MessagingException e) {
                    throw e;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
}