From e561d0c4faefce7f0e32e15a5667b6512c6341d7 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Wed, 29 Mar 2017 00:32:38 +0300 Subject: juick-notifications: refactor using with Spring annotations --- .../java/com/juick/components/Notifications.java | 144 ++++----------------- 1 file changed, 28 insertions(+), 116 deletions(-) (limited to 'juick-notifications/src/main/java/com/juick/components/Notifications.java') diff --git a/juick-notifications/src/main/java/com/juick/components/Notifications.java b/juick-notifications/src/main/java/com/juick/components/Notifications.java index 00f63136..673ea402 100644 --- a/juick-notifications/src/main/java/com/juick/components/Notifications.java +++ b/juick-notifications/src/main/java/com/juick/components/Notifications.java @@ -17,30 +17,17 @@ */ package com.juick.components; -import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.android.gcm.server.*; import com.juick.TokensList; -import com.juick.components.mpns.MPNSError; -import com.juick.components.mpns.MPNSToken; import com.notnoop.apns.APNS; import com.notnoop.apns.ApnsService; import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; -import org.apache.http.*; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; -import org.apache.http.util.TextUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.core.env.Environment; import org.springframework.http.HttpMethod; import org.springframework.web.client.RestTemplate; import rocks.xmpp.core.XmppException; @@ -57,52 +44,31 @@ import java.util.stream.Collectors; /** * @author Ugnich Anton */ -public class Notifications implements AutoCloseable { +public class Notifications implements NotificationClientListener, AutoCloseable { private static Logger logger = LoggerFactory.getLogger(Notifications.class); - private final RestTemplate rest; + @Inject + private RestTemplate rest; + @Inject private ExternalComponent xmpp; - private final Sender GCMSender; - - private final String wns_application_sip; - private final String wns_client_secret; - private final String pushJid; - private final String xmppHost; - private final int xmppPort; - private final String xmppPushPassword; + @Inject + private Sender GCMSender; - private final ObjectMapper mapper; + @Inject + private ObjectMapper jsonMapper; - private final Set invalidGCMTokens; - private final Set invalidMPNSTokens; + private final Set invalidGCMTokens = Collections.synchronizedSet(new HashSet<>()); + private final Set invalidMPNSTokens = Collections.synchronizedSet(new HashSet<>()); + @Inject + private MPNSClient mpnsClient; @Inject private ApnsService apns; - - public Notifications(final Environment env, final RestTemplate rest) { - this.rest = rest; - wns_application_sip = env.getProperty("wns_application_sip", StringUtils.EMPTY); - wns_client_secret = env.getProperty("wns_client_secret", StringUtils.EMPTY); - GCMSender = new Sender(env.getProperty("gcm_key", StringUtils.EMPTY), Endpoint.GCM); - pushJid = env.getProperty("push_jid"); - xmppHost = env.getProperty("xmpp_host", "localhost"); - xmppPort = NumberUtils.toInt(env.getProperty("xmpp_port"), 5347); - xmppPushPassword = env.getProperty("push_xmpp_password", StringUtils.EMPTY); - mapper = new ObjectMapper(); - mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT); - invalidGCMTokens = Collections.synchronizedSet(new HashSet<>()); - invalidMPNSTokens = Collections.synchronizedSet(new HashSet<>()); - } - @PostConstruct - public void init() { - XmppSessionConfiguration configuration = XmppSessionConfiguration.builder() - .extensions(Extension.of(com.juick.Message.class)) - .build(); - xmpp = ExternalComponent.create(pushJid, xmppPushPassword, configuration, xmppHost, xmppPort); + public void init() throws IOException { + mpnsClient.authenticate(); + mpnsClient.setListener(this); xmpp.addInboundMessageListener(e -> { rocks.xmpp.core.stanza.model.Message msg = e.getMessage(); com.juick.Message jmsg = msg.getExtension(com.juick.Message.class); @@ -135,11 +101,7 @@ public class Notifications implements AutoCloseable { .flatMap(t -> t.getTokens().stream()).collect(Collectors.toList()); if (!regids.isEmpty()) { try { - ObjectMapper messageSerializer = new ObjectMapper(); - messageSerializer.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); - messageSerializer.setSerializationInclusion(JsonInclude.Include.NON_NULL); - messageSerializer.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT); - String json = messageSerializer.writeValueAsString(jmsg); + String json = jsonMapper.writeValueAsString(jmsg); logger.info(json); Message message = new Message.Builder().addData("message", json).build(); MulticastResult result = GCMSender.send(message, regids, 3); @@ -173,7 +135,6 @@ public class Notifications implements AutoCloseable { logger.info("WNS: no recipients"); } else { try { - String wnsToken = getWnsAccessToken(); String text1 = "@" + jmsg.getUser().getName(); if (!jmsg.getTags().isEmpty()) { text1 += ":" + StringEscapeUtils.escapeXml11(jmsg.getTagsString()); @@ -195,7 +156,7 @@ public class Notifications implements AutoCloseable { logger.trace(xml); for (String url : urls) { logger.info("WNS: {}", url); - sendWNS(wnsToken, url, xml); + mpnsClient.sendNotification(url, xml); } } catch (IOException | IllegalStateException ex) { logger.error("WNS: ", ex); @@ -230,66 +191,6 @@ public class Notifications implements AutoCloseable { logger.info("ExternalComponent on notifications destroyed"); } - String getWnsAccessToken() throws IOException, IllegalStateException { - if (TextUtils.isEmpty(wns_application_sip)) { - throw new IllegalStateException("'wns_application_sip' is not initialized"); - } - if (TextUtils.isEmpty(wns_client_secret)) { - throw new IllegalStateException("'wns_client_secret' is not initialized"); - } - HttpClient client = HttpClientBuilder.create().build(); - String url = "https://login.live.com/accesstoken.srf"; - List formParams = new ArrayList<>(); - formParams.add(new BasicNameValuePair("grant_type", "client_credentials")); - formParams.add(new BasicNameValuePair("client_id", wns_application_sip)); - formParams.add(new BasicNameValuePair("client_secret", wns_client_secret)); - formParams.add(new BasicNameValuePair("scope", "notify.windows.com")); - UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8); - HttpPost httppost = new HttpPost(url); - httppost.setEntity(entity); - HttpResponse response = client.execute(httppost); - int statusCode = response.getStatusLine().getStatusCode(); - String responseContent = EntityUtils.toString(response.getEntity(), Consts.UTF_8); - if (statusCode != HttpStatus.SC_OK) { - MPNSError error = mapper.readValue(responseContent, MPNSError.class); - throw new IOException(error.getError() + ": " + error.getErrorDescription()); - } - MPNSToken token = mapper.readValue(responseContent, MPNSToken.class); - if (token.getTokenType().length() >= 1) { - token.setTokenType(Character.toUpperCase(token.getTokenType().charAt(0)) + token.getTokenType().substring(1)); - } - return token.getTokenType() + " " + token.getAccessToken(); - } - - void sendWNS(final String wnsToken, final String url, final String xml) throws IOException { - HttpClient client = HttpClientBuilder.create().build(); - StringEntity entity = new StringEntity(xml, Consts.UTF_8); - HttpPost httpPost = new HttpPost(url); - httpPost.setHeader("Content-Type", "text/xml"); - httpPost.setHeader("Authorization", wnsToken); - httpPost.setHeader("X-WNS-Type", "wns/toast"); - httpPost.setEntity(entity); - HttpResponse response = client.execute(httpPost); - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode != HttpStatus.SC_OK) { - if (statusCode == HttpStatus.SC_GONE) { - // expired - logger.info("{} is scheduled to remove", url); - addInvalidMPNSToken(url); - } else { - String headersContent = stringifyWnsHttpHeaders(response.getAllHeaders()); - throw new IOException(headersContent); - } - } - } - - static String stringifyWnsHttpHeaders(final Header[] allHeaders) { - return Arrays.stream(allHeaders) - .filter(x -> x.getName().startsWith("X-WNS-") || x.getName().startsWith("WWW-")) - .map(x -> x.getName() + ": " + x.getValue()) - .collect(Collectors.joining("\n")); - } - public void addInvalidGCMToken(String token) { synchronized (invalidGCMTokens) { invalidGCMTokens.add(token); @@ -318,4 +219,15 @@ public class Notifications implements AutoCloseable { invalidMPNSTokens.clear(); } } + + @Override + public void invalidToken(String type, String token) { + switch (type) { + case "mpns": + addInvalidMPNSToken(token); + break; + default: + break; + } + } } -- cgit v1.2.3