diff options
author | Vitaly Takmazov | 2018-09-25 12:49:57 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2018-09-25 12:49:57 +0300 |
commit | 15753b2ebdac2ab49cf5682c417851a0653e136e (patch) | |
tree | 81efc43348a820a1c647779f78264bce10103b59 | |
parent | ae76024011a8442ae7eab953e0b97e9fe2c7c201 (diff) |
notifications server refactoring
12 files changed, 334 insertions, 228 deletions
diff --git a/juick-common/src/main/java/com/juick/service/component/MessageReadEvent.java b/juick-common/src/main/java/com/juick/service/component/MessageReadEvent.java index 82cfadd5..b314b89b 100644 --- a/juick-common/src/main/java/com/juick/service/component/MessageReadEvent.java +++ b/juick-common/src/main/java/com/juick/service/component/MessageReadEvent.java @@ -4,22 +4,24 @@ import com.juick.Message; import com.juick.User; import org.springframework.context.ApplicationEvent; +import java.util.List; + public class MessageReadEvent extends ApplicationEvent { - private User user; + private List<User> users; private Message message; /** * Create a new ApplicationEvent. * * @param source the object on which the event initially occurred (never {@code null}) */ - public MessageReadEvent(Object source, User user, Message message) { + public MessageReadEvent(Object source, List<User> users, Message message) { super(source); - this.user = user; + this.users = users; this.message = message; } - public User getUser() { - return user; + public List<User> getUsers() { + return users; } public Message getMessage() { diff --git a/juick-server/src/main/java/com/juick/server/NotificationListener.java b/juick-common/src/main/java/com/juick/service/component/NotificationListener.java index 750c8b18..e4ccb13b 100644 --- a/juick-server/src/main/java/com/juick/server/NotificationListener.java +++ b/juick-common/src/main/java/com/juick/service/component/NotificationListener.java @@ -1,6 +1,5 @@ -package com.juick.server; +package com.juick.service.component; -import com.juick.service.component.*; import org.springframework.context.event.EventListener; public interface NotificationListener { diff --git a/juick-notifications/build.gradle b/juick-notifications/build.gradle index b5b7bd89..203931ee 100644 --- a/juick-notifications/build.gradle +++ b/juick-notifications/build.gradle @@ -3,10 +3,7 @@ apply plugin: 'org.springframework.boot' dependencies { compile project(':juick-common') - compile("org.springframework.boot:spring-boot-starter-websocket") { - exclude module: "spring-boot-starter-tomcat" - exclude module: "spring-boot-starter-web" - } + compile("org.springframework.boot:spring-boot-starter-websocket") compile 'com.ganyo:gcm-server:1.1.0' compile 'com.turo:pushy:0.13.4' } diff --git a/juick-notifications/src/main/java/com/juick/components/APNSManager.java b/juick-notifications/src/main/java/com/juick/components/APNSManager.java new file mode 100644 index 00000000..c0380847 --- /dev/null +++ b/juick-notifications/src/main/java/com/juick/components/APNSManager.java @@ -0,0 +1,140 @@ +package com.juick.components; + +import com.juick.ExternalToken; +import com.juick.User; +import com.juick.formatters.PlainTextFormatter; +import com.juick.service.component.*; +import com.turo.pushy.apns.ApnsClient; +import com.turo.pushy.apns.ApnsClientBuilder; +import com.turo.pushy.apns.PushNotificationResponse; +import com.turo.pushy.apns.auth.ApnsSigningKey; +import com.turo.pushy.apns.util.ApnsPayloadBuilder; +import com.turo.pushy.apns.util.SimpleApnsPushNotification; +import com.turo.pushy.apns.util.concurrent.PushNotificationResponseListener; +import io.netty.util.concurrent.Future; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.inject.Inject; +import java.io.File; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Date; +import java.util.List; +import java.util.Optional; + +public class APNSManager implements NotificationListener { + private static Logger logger = LoggerFactory.getLogger(APNSManager.class); + + private ApnsClient apns; + @Value("${ios_p8_key:}") + private String p8key; + @Value("${ios_app_id:}") + private String topic; + @Value("${ios_team_id:}") + private String teamId; + @Value("${ios_key_id:}") + private String keyId; + @Inject + private NotificationsManager notificationsManager; + @PostConstruct + public void initialize() throws NoSuchAlgorithmException, InvalidKeyException, IOException { + apns = new ApnsClientBuilder() + .setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST) + .setSigningKey(ApnsSigningKey.loadFromPkcs8File(new File(p8key), + teamId, keyId)) + .build(); + } + @Override + public void processMessageEvent(MessageEvent messageEvent) { + com.juick.Message jmsg = messageEvent.getMessage(); + List<User> users = messageEvent.getUsers(); + ApnsPayloadBuilder apnsPayloadBuilder = new ApnsPayloadBuilder(); + apnsPayloadBuilder.addCustomProperty("mid", jmsg.getMid()); + apnsPayloadBuilder.addCustomProperty("uname", jmsg.getUser().getName()); + String post = PlainTextFormatter.formatPost(jmsg); + String[] parts = post.split("\n", 2); + apnsPayloadBuilder.setAlertTitle(parts[0]).setAlertBody(parts[1]); + users.forEach( user -> { + apnsPayloadBuilder.setBadgeNumber(user.getUnreadCount()); + String payload = apnsPayloadBuilder.buildWithDefaultMaximumLength(); + user.getTokens().stream().filter(t -> t.getType().equals("apns")) + .map(ExternalToken::getToken).forEach(token -> { + Future<PushNotificationResponse<SimpleApnsPushNotification>> notification = apns.sendNotification( + new SimpleApnsPushNotification(token, topic, payload)); + notification.addListener((PushNotificationResponseListener<SimpleApnsPushNotification>) future -> { + if (future.isSuccess()) { + processAPNSResponse(token, future.getNow()); + } else { + logger.warn("APNS error ", future.cause()); + } + }); + }); + }); + } + + @Override + public void processSubscribeEvent(SubscribeEvent subscribeEvent) { + + } + + @Override + public void processLikeEvent(LikeEvent likeEvent) { + + } + + @Override + public void processPingEvent(PingEvent pingEvent) { + + } + + @Override + public void processMessageReadEvent(MessageReadEvent messageReadEvent) { + List<User> users = messageReadEvent.getUsers(); + ApnsPayloadBuilder apnsPayloadBuilder = new ApnsPayloadBuilder(); + users.forEach(user -> { + apnsPayloadBuilder.setBadgeNumber(user.getUnreadCount()); + String payload = apnsPayloadBuilder.buildWithDefaultMaximumLength(); + user.getTokens().stream().filter(t -> t.getType().equals("apns")) + .map(ExternalToken::getToken).forEach(token -> { + Future<PushNotificationResponse<SimpleApnsPushNotification>> notification = apns.sendNotification( + new SimpleApnsPushNotification(token, topic, payload)); + notification.addListener((PushNotificationResponseListener<SimpleApnsPushNotification>) future -> { + if (future.isSuccess()) { + processAPNSResponse(token, future.getNow()); + } else { + logger.warn("APNS error ", future.cause()); + } + }); + }); + }); + } + @PreDestroy + public void close() { + apns.close(); + } + + private void processAPNSResponse(String token, PushNotificationResponse<SimpleApnsPushNotification> pushNotificationResponse) { + if (pushNotificationResponse.isAccepted()) { + logger.info("APNS accepted: {}", token); + } else { + String reason = pushNotificationResponse.getRejectionReason(); + logger.info("APNS rejected: {}", reason); + if (reason.equals("BadDeviceToken")) { + notificationsManager.getInvalidAPNSTokens().add(token); + } + } + Optional<Date> invalidationDate = Optional.ofNullable( + pushNotificationResponse.getTokenInvalidationTimestamp()); + invalidationDate.ifPresent(date -> { + if (date.before(new Date())) { + logger.info("Token invalidated: {}", token); + notificationsManager.getInvalidAPNSTokens().add(token); + } + }); + } +} diff --git a/juick-notifications/src/main/java/com/juick/components/FirebaseManager.java b/juick-notifications/src/main/java/com/juick/components/FirebaseManager.java new file mode 100644 index 00000000..54e7c97a --- /dev/null +++ b/juick-notifications/src/main/java/com/juick/components/FirebaseManager.java @@ -0,0 +1,90 @@ +package com.juick.components; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.android.gcm.server.*; +import com.juick.ExternalToken; +import com.juick.User; +import com.juick.service.component.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class FirebaseManager implements NotificationListener { + private static Logger logger = LoggerFactory.getLogger(FirebaseManager.class); + @Inject + ObjectMapper jsonMapper; + @Value("${gcm_key:}") + private String gcmKey; + @Inject + private NotificationsManager notificationsManager; + + private Sender GCMSender; + + @PostConstruct + public void initialize() { + GCMSender = new Sender(gcmKey, Endpoint.GCM); + } + + @Override + public void processMessageEvent(MessageEvent messageEvent) { + com.juick.Message jmsg = messageEvent.getMessage(); + List<User> users = messageEvent.getUsers(); + // GCM + List<String> regids = users.stream().flatMap(u -> u.getTokens().stream()).filter(d -> d.getType().equals("gcm")) + .map(ExternalToken::getToken).collect(Collectors.toList()); + if (!regids.isEmpty()) { + try { + String json = jsonMapper.writeValueAsString(jmsg); + logger.info(json); + Message message = new Message.Builder().addData("message", json).build(); + MulticastResult result = GCMSender.send(message, regids, 3); + List<Result> results = result.getResults(); + for (int i = 0; i < results.size(); i++) { + Result currentResult = results.get(i); + logger.info("RES {}: {}", i, currentResult); + List<String> errorCodes = Arrays.asList(Constants.ERROR_MISMATCH_SENDER_ID, Constants.ERROR_NOT_REGISTERED); + if (errorCodes.contains(currentResult.getErrorCodeName())) { + // assuming results are in order of regids + // http://stackoverflow.com/a/11594531/1097384 + String currentId = regids.get(i); + logger.info("{} is scheduled to remove", currentId); + notificationsManager.addInvalidGCMToken(currentId); + } + } + } catch (IOException ex) { + logger.error(ex.getMessage(), ex); + } catch (IllegalArgumentException err) { + logger.warn("Android: Invalid API Key", err); + } + } else { + logger.info("GMS: no recipients"); + } + } + + @Override + public void processSubscribeEvent(SubscribeEvent subscribeEvent) { + + } + + @Override + public void processLikeEvent(LikeEvent likeEvent) { + + } + + @Override + public void processPingEvent(PingEvent pingEvent) { + + } + + @Override + public void processMessageReadEvent(MessageReadEvent messageReadEvent) { + + } +} diff --git a/juick-notifications/src/main/java/com/juick/components/MPNSClient.java b/juick-notifications/src/main/java/com/juick/components/MPNSManager.java index efa47bb1..56c2df8d 100644 --- a/juick-notifications/src/main/java/com/juick/components/MPNSClient.java +++ b/juick-notifications/src/main/java/com/juick/components/MPNSManager.java @@ -1,9 +1,14 @@ package com.juick.components; import com.fasterxml.jackson.databind.ObjectMapper; +import com.juick.ExternalToken; +import com.juick.User; import com.juick.components.mpns.MPNSError; import com.juick.components.mpns.MPNSToken; -import org.apache.commons.collections4.MapUtils; +import com.juick.service.component.*; +import com.juick.util.MessageUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.text.StringEscapeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -19,19 +24,18 @@ import javax.annotation.PostConstruct; import javax.inject.Inject; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.List; import java.util.stream.Collectors; /** * Created by vital on 29.03.2017. */ -public class MPNSClient { +public class MPNSManager implements NotificationListener { - private static Logger logger = LoggerFactory.getLogger(MPNSClient.class); + private static Logger logger = LoggerFactory.getLogger(MPNSManager.class); private String accessToken; - private NotificationClientListener listener; - @Inject private ObjectMapper jsonMapper; @Value("${wns_application_sip:}") @@ -40,6 +44,9 @@ public class MPNSClient { private String applicationSecret; private RestTemplate wnsService; + @Inject + private NotificationsManager notificationsManager; + @PostConstruct public void authenticate() throws IOException { String url = "https://login.live.com/accesstoken.srf"; @@ -82,7 +89,7 @@ public class MPNSClient { if (statusCode == HttpStatus.GONE) { // expired logger.info("{} is scheduled to remove", url); - listener.invalidToken("mpns", url); + notificationsManager.addInvalidMPNSToken(url); } else { String headersContent = ex.getResponseHeaders().entrySet().stream() .filter(x -> x.getKey().startsWith("X-WNS-") || x.getKey().startsWith("WWW-")) @@ -93,8 +100,64 @@ public class MPNSClient { } } + @Override + public void processMessageEvent(MessageEvent messageEvent) { + com.juick.Message jmsg = messageEvent.getMessage(); + List<User> users = messageEvent.getUsers(); + + List<String> urls = users.stream().flatMap(u -> u.getTokens().stream()).filter(d -> d.getType().equals("mpns")) + .map(ExternalToken::getToken).collect(Collectors.toList()); + + if (urls.isEmpty()) { + logger.info("WNS: no recipients"); + } else { + try { + String text1 = "@" + jmsg.getUser().getName(); + if (!jmsg.getTags().isEmpty()) { + text1 += ":" + StringEscapeUtils.escapeXml11(MessageUtils.getTagsString(jmsg)); + } + String text2 = StringEscapeUtils.escapeXml11(StringUtils.defaultString(jmsg.getText())); + String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + + "<toast>" + + "<visual>" + + "<binding template=\"ToastImageAndText02\">" + + "<image id=\"1\" src=\"http://i.juick.com/as/" + jmsg.getUser().getUid() + ".png\" />" + + "<text id=\"1\">" + text1 + "</text>" + + "<text id=\"2\">" + text2 + "</text>" + + "</binding>" + + "</visual>" + + "<commands>" + + "<command arguments=\"/ThreadView.xaml?mid=" + jmsg.getMid() + "\" />" + + "</commands>" + + "</toast>"; + logger.trace(xml); + for (String url : urls) { + logger.info("WNS: {}", url); + sendNotification(url, xml); + } + } catch (IOException | IllegalStateException ex) { + logger.error("WNS: ", ex); + } + } + } + + @Override + public void processSubscribeEvent(SubscribeEvent subscribeEvent) { + + } + + @Override + public void processLikeEvent(LikeEvent likeEvent) { + + } + + @Override + public void processPingEvent(PingEvent pingEvent) { + + } + + @Override + public void processMessageReadEvent(MessageReadEvent messageReadEvent) { - public void setListener(NotificationClientListener listener) { - this.listener = listener; } } diff --git a/juick-notifications/src/main/java/com/juick/components/NotificationClientListener.java b/juick-notifications/src/main/java/com/juick/components/NotificationClientListener.java deleted file mode 100644 index 46bd683f..00000000 --- a/juick-notifications/src/main/java/com/juick/components/NotificationClientListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.juick.components; - -/** - * Created by vital on 29.03.2017. - */ -public interface NotificationClientListener { - void invalidToken(String type, String token); -} diff --git a/juick-notifications/src/main/java/com/juick/components/Notifications.java b/juick-notifications/src/main/java/com/juick/components/NotificationsManager.java index 1842593a..be97ea40 100644 --- a/juick-notifications/src/main/java/com/juick/components/Notifications.java +++ b/juick-notifications/src/main/java/com/juick/components/NotificationsManager.java @@ -18,23 +18,14 @@ package com.juick.components; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.android.gcm.server.*; import com.juick.ExternalToken; import com.juick.User; -import com.juick.formatters.PlainTextFormatter; import com.juick.service.component.DisconnectedEvent; +import com.juick.service.component.MessageEvent; +import com.juick.service.component.MessageReadEvent; import com.juick.util.MessageUtils; -import com.turo.pushy.apns.ApnsClient; -import com.turo.pushy.apns.PushNotificationResponse; -import com.turo.pushy.apns.util.ApnsPayloadBuilder; -import com.turo.pushy.apns.util.SimpleApnsPushNotification; -import com.turo.pushy.apns.util.concurrent.PushNotificationResponseListener; -import io.netty.util.concurrent.Future; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.text.StringEscapeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationEventPublisher; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; @@ -64,13 +55,11 @@ import java.util.stream.Collectors; * @author Ugnich Anton */ @Component -public class Notifications extends TextWebSocketHandler implements NotificationClientListener { - private static Logger logger = LoggerFactory.getLogger(Notifications.class); +public class NotificationsManager extends TextWebSocketHandler { + private static Logger logger = LoggerFactory.getLogger(NotificationsManager.class); @Inject private RestTemplate rest; - @Inject - private Sender GCMSender; @Inject private ObjectMapper jsonMapper; @@ -79,16 +68,8 @@ public class Notifications extends TextWebSocketHandler implements NotificationC private final Set<String> invalidMPNSTokens = Collections.synchronizedSet(new HashSet<>()); private final Set<String> invalidAPNSTokens = Collections.synchronizedSet(new HashSet<>()); - @Inject - private MPNSClient mpnsClient; - @Inject - private ApnsClient apns; - @Value("${ios_app_id:}") - private String topic; - @PostConstruct public void init() { - mpnsClient.setListener(this); closeFlag.set(false); } public void messageReceived(@Nonnull com.juick.Message jmsg) { @@ -114,144 +95,15 @@ public class Notifications extends TextWebSocketHandler implements NotificationC HttpMethod.GET, null, new ParameterizedTypeReference<List<User>>() { }).getBody()); } - - // GCM - List<String> regids = users.stream().flatMap(u -> u.getTokens().stream()).filter(d -> d.getType().equals("gcm")) - .map(ExternalToken::getToken).collect(Collectors.toList()); - if (!regids.isEmpty()) { - try { - String json = jsonMapper.writeValueAsString(jmsg); - logger.info(json); - Message message = new Message.Builder().addData("message", json).build(); - MulticastResult result = GCMSender.send(message, regids, 3); - List<Result> results = result.getResults(); - for (int i = 0; i < results.size(); i++) { - Result currentResult = results.get(i); - logger.info("RES {}: {}", i, currentResult); - List<String> errorCodes = Arrays.asList(Constants.ERROR_MISMATCH_SENDER_ID, Constants.ERROR_NOT_REGISTERED); - if (errorCodes.contains(currentResult.getErrorCodeName())) { - // assuming results are in order of regids - // http://stackoverflow.com/a/11594531/1097384 - String currentId = regids.get(i); - logger.info("{} is scheduled to remove", currentId); - addInvalidGCMToken(currentId); - } - } - } catch (IOException ex) { - logger.error(ex.getMessage(), ex); - } catch (IllegalArgumentException err) { - logger.warn("Android: Invalid API Key", err); - } - } else { - logger.info("GMS: no recipients"); - } - - /*** WinPhone ***/ - List<String> urls = users.stream().flatMap(u -> u.getTokens().stream()).filter(d -> d.getType().equals("mpns")) - .map(ExternalToken::getToken).collect(Collectors.toList()); - - if (urls.isEmpty()) { - logger.info("WNS: no recipients"); - } else { - try { - String text1 = "@" + jmsg.getUser().getName(); - if (!jmsg.getTags().isEmpty()) { - text1 += ":" + StringEscapeUtils.escapeXml11(MessageUtils.getTagsString(jmsg)); - } - String text2 = StringEscapeUtils.escapeXml11(StringUtils.defaultString(jmsg.getText())); - String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" - + "<toast>" - + "<visual>" - + "<binding template=\"ToastImageAndText02\">" - + "<image id=\"1\" src=\"http://i.juick.com/as/" + jmsg.getUser().getUid() + ".png\" />" - + "<text id=\"1\">" + text1 + "</text>" - + "<text id=\"2\">" + text2 + "</text>" - + "</binding>" - + "</visual>" - + "<commands>" - + "<command arguments=\"/ThreadView.xaml?mid=" + jmsg.getMid() + "\" />" - + "</commands>" - + "</toast>"; - logger.trace(xml); - for (String url : urls) { - logger.info("WNS: {}", url); - mpnsClient.sendNotification(url, xml); - } - } catch (IOException | IllegalStateException ex) { - logger.error("WNS: ", ex); - } - } - - /*** iOS ***/ - ApnsPayloadBuilder apnsPayloadBuilder = new ApnsPayloadBuilder(); - apnsPayloadBuilder.addCustomProperty("mid", jmsg.getMid()); - apnsPayloadBuilder.addCustomProperty("uname", jmsg.getUser().getName()); - String post = PlainTextFormatter.formatPost(jmsg); - String[] parts = post.split("\n", 2); - apnsPayloadBuilder.setAlertTitle(parts[0]).setAlertBody(parts[1]); - users.forEach( user -> { - apnsPayloadBuilder.setBadgeNumber(user.getUnreadCount()); - String payload = apnsPayloadBuilder.buildWithDefaultMaximumLength(); - user.getTokens().stream().filter(t -> t.getType().equals("apns")) - .map(ExternalToken::getToken).forEach(token -> { - Future<PushNotificationResponse<SimpleApnsPushNotification>> notification = apns.sendNotification( - new SimpleApnsPushNotification(token, topic, payload)); - notification.addListener((PushNotificationResponseListener<SimpleApnsPushNotification>) future -> { - if (future.isSuccess()) { - processAPNSResponse(token, future.getNow()); - } else { - logger.warn("APNS error ", future.cause()); - } - }); - }); - }); + applicationEventPublisher.publishEvent(new MessageEvent(this, jmsg, users)); } private void serviceMessageReceived(@Nonnull com.juick.Message jmsg) { logger.info("Message read event from {} for {}", jmsg.getUser().getName(), jmsg.getMid()); - // iOS List<User> users = rest.exchange(String.format("http://api.juick.com/notifications?uid=%d", jmsg.getUser().getUid()), HttpMethod.GET, null, new ParameterizedTypeReference<List<User>>() { }).getBody(); - ApnsPayloadBuilder apnsPayloadBuilder = new ApnsPayloadBuilder(); - users.forEach(user -> { - apnsPayloadBuilder.setBadgeNumber(user.getUnreadCount()); - String payload = apnsPayloadBuilder.buildWithDefaultMaximumLength(); - user.getTokens().stream().filter(t -> t.getType().equals("apns")) - .map(ExternalToken::getToken).forEach(token -> { - Future<PushNotificationResponse<SimpleApnsPushNotification>> notification = apns.sendNotification( - new SimpleApnsPushNotification(token, topic, payload)); - notification.addListener((PushNotificationResponseListener<SimpleApnsPushNotification>) future -> { - if (future.isSuccess()) { - processAPNSResponse(token, future.getNow()); - } else { - logger.warn("APNS error ", future.cause()); - } - }); - }); - }); - } - - private void processAPNSResponse(String token, PushNotificationResponse<SimpleApnsPushNotification> pushNotificationResponse) { - if (!closeFlag.get()) { - if (pushNotificationResponse.isAccepted()) { - logger.info("APNS accepted: {}", token); - } else { - String reason = pushNotificationResponse.getRejectionReason(); - logger.info("APNS rejected: {}", reason); - if (reason.equals("BadDeviceToken")) { - invalidAPNSTokens.add(token); - } - } - Optional<Date> invalidationDate = Optional.ofNullable( - pushNotificationResponse.getTokenInvalidationTimestamp()); - invalidationDate.ifPresent(date -> { - if (date.before(new Date())) { - logger.info("Token invalidated: {}", token); - invalidAPNSTokens.add(token); - } - }); - } + applicationEventPublisher.publishEvent(new MessageReadEvent(this, users, jmsg)); } public void addInvalidGCMToken(String token) { @@ -283,17 +135,6 @@ public class Notifications extends TextWebSocketHandler implements NotificationC } } - @Override - public void invalidToken(String type, String token) { - switch (type) { - case "mpns": - addInvalidMPNSToken(token); - break; - default: - break; - } - } - public Set<String> getInvalidAPNSTokens() { return invalidAPNSTokens; } @@ -343,7 +184,6 @@ public class Notifications extends TextWebSocketHandler implements NotificationC } @PreDestroy public void close() { - apns.close(); closeFlag.set(true); } @Scheduled(fixedRate = 600000) diff --git a/juick-notifications/src/main/java/com/juick/components/configuration/APNSConfiguration.java b/juick-notifications/src/main/java/com/juick/components/configuration/APNSConfiguration.java index 43ea3943..fbc17bc9 100644 --- a/juick-notifications/src/main/java/com/juick/components/configuration/APNSConfiguration.java +++ b/juick-notifications/src/main/java/com/juick/components/configuration/APNSConfiguration.java @@ -1,34 +1,18 @@ package com.juick.components.configuration; -import com.turo.pushy.apns.ApnsClient; -import com.turo.pushy.apns.ApnsClientBuilder; -import com.turo.pushy.apns.auth.ApnsSigningKey; -import org.springframework.beans.factory.annotation.Value; +import com.juick.components.APNSManager; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import java.io.File; -import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; - /** * Created by vital on 28.03.2017. */ @Configuration +@ConditionalOnProperty(name = "ios_p8_key") public class APNSConfiguration { - @Value("${ios_p8_key:}") - private String p8key; - @Value("${ios_team_id:}") - private String teamId; - @Value("${ios_key_id:}") - private String keyId; @Bean - public ApnsClient apns() throws NoSuchAlgorithmException, InvalidKeyException, IOException { - return new ApnsClientBuilder() - .setApnsServer(ApnsClientBuilder.PRODUCTION_APNS_HOST) - .setSigningKey(ApnsSigningKey.loadFromPkcs8File(new File(p8key), - teamId, keyId)) - .build(); + public APNSManager apnsManager() { + return new APNSManager(); } } diff --git a/juick-notifications/src/main/java/com/juick/components/configuration/GCMConfiguration.java b/juick-notifications/src/main/java/com/juick/components/configuration/GCMConfiguration.java index 27e1af0f..68d9f017 100644 --- a/juick-notifications/src/main/java/com/juick/components/configuration/GCMConfiguration.java +++ b/juick-notifications/src/main/java/com/juick/components/configuration/GCMConfiguration.java @@ -1,8 +1,7 @@ package com.juick.components.configuration; -import com.google.android.gcm.server.Endpoint; -import com.google.android.gcm.server.Sender; -import org.springframework.beans.factory.annotation.Value; +import com.juick.components.FirebaseManager; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -10,12 +9,11 @@ import org.springframework.context.annotation.Configuration; * Created by vital on 29.03.2017. */ @Configuration +@ConditionalOnProperty(name = "gcm_key") public class GCMConfiguration { - @Value("${gcm_key:}") - private String gcmKey; @Bean - public Sender GCMSender() { - return new Sender(gcmKey, Endpoint.GCM); + public FirebaseManager firebaseManager() { + return new FirebaseManager(); } } diff --git a/juick-notifications/src/main/java/com/juick/components/configuration/JuickServerWebsocketConfiguration.java b/juick-notifications/src/main/java/com/juick/components/configuration/JuickServerWebsocketConfiguration.java index c35dfc7d..deb0cb5b 100644 --- a/juick-notifications/src/main/java/com/juick/components/configuration/JuickServerWebsocketConfiguration.java +++ b/juick-notifications/src/main/java/com/juick/components/configuration/JuickServerWebsocketConfiguration.java @@ -1,14 +1,13 @@ package com.juick.components.configuration; import com.fasterxml.jackson.databind.ObjectMapper; -import com.juick.components.Notifications; +import com.juick.components.NotificationsManager; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpRequestInterceptor; @@ -40,7 +39,7 @@ public class JuickServerWebsocketConfiguration { @Inject ObjectMapper jsonMapper; @Inject - private Notifications notifications; + private NotificationsManager notificationsManager; @Bean public RestTemplate rest() { RestTemplate rest = new RestTemplate(); @@ -62,7 +61,7 @@ public class JuickServerWebsocketConfiguration { } String websocketURI = UriComponentsBuilder.fromUriString(baseUri) .queryParam("hash", hash).build().toUriString(); - WebSocketConnectionManager manager = new WebSocketConnectionManager(client(), notifications, websocketURI); + WebSocketConnectionManager manager = new WebSocketConnectionManager(client(), notificationsManager, websocketURI); return manager; } @Bean diff --git a/juick-notifications/src/main/java/com/juick/components/configuration/MPNSConfiguration.java b/juick-notifications/src/main/java/com/juick/components/configuration/MPNSConfiguration.java index f849b159..4235486c 100644 --- a/juick-notifications/src/main/java/com/juick/components/configuration/MPNSConfiguration.java +++ b/juick-notifications/src/main/java/com/juick/components/configuration/MPNSConfiguration.java @@ -1,6 +1,7 @@ package com.juick.components.configuration; -import com.juick.components.MPNSClient; +import com.juick.components.MPNSManager; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -8,9 +9,10 @@ import org.springframework.context.annotation.Configuration; * Created by vital on 29.03.2017. */ @Configuration +@ConditionalOnProperty(name = "wns_application_sip") public class MPNSConfiguration { @Bean - public MPNSClient mpnsClient() { - return new MPNSClient(); + public MPNSManager mpnsClient() { + return new MPNSManager(); } } |