aboutsummaryrefslogtreecommitdiff
path: root/juick-notifications
diff options
context:
space:
mode:
Diffstat (limited to 'juick-notifications')
-rw-r--r--juick-notifications/src/main/java/com/juick/components/Notifications.java111
-rw-r--r--juick-notifications/src/main/java/com/juick/components/configuration/NotificationsAppConfiguration.java40
-rw-r--r--juick-notifications/src/main/java/com/juick/components/configuration/NotificationsConfiguration.java122
-rw-r--r--juick-notifications/src/main/java/com/juick/components/configuration/NotificationsInitializer.java10
-rw-r--r--juick-notifications/src/main/java/com/juick/components/configuration/NotificationsMvcConfiguration.java41
5 files changed, 153 insertions, 171 deletions
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 129934188..b7e6b2b8b 100644
--- a/juick-notifications/src/main/java/com/juick/components/Notifications.java
+++ b/juick-notifications/src/main/java/com/juick/components/Notifications.java
@@ -19,6 +19,7 @@ package com.juick.components;
import com.google.android.gcm.server.*;
import com.juick.json.MessageSerializer;
+import com.juick.util.ThreadHelper;
import com.juick.xmpp.JID;
import com.juick.xmpp.Message.MessageListener;
import com.juick.xmpp.Stream;
@@ -44,13 +45,12 @@ import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpMethod;
-import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
-import javax.inject.Inject;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
@@ -59,63 +59,75 @@ import java.util.List;
import java.util.concurrent.ExecutorService;
/**
- *
* @author Ugnich Anton
*/
-public class Notifications implements DisposableBean, Stream.StreamListener, MessageListener {
-
+public class Notifications implements InitializingBean, DisposableBean, Stream.StreamListener, MessageListener {
private static Logger logger = LoggerFactory.getLogger(Notifications.class);
- String wns_application_sip;
- String wns_client_secret;
- @Inject
- RestTemplate rest;
- Socket socket;
- Stream xmpp;
- Sender GCMSender;
- ExecutorService service;
+ private final RestTemplate rest;
+ private final ExecutorService service;
+ private Socket socket;
+ private Stream 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
- public Notifications(Environment env, ExecutorService service) {
+
+ public Notifications(final Environment env, final ExecutorService service, final RestTemplate rest) {
this.service = service;
- logger.info("component initialized");
+ this.rest = rest;
+
wns_application_sip = env.getProperty("wns_application_sip", "");
wns_client_secret = env.getProperty("wns_client_secret", "");
GCMSender = new Sender(env.getProperty("gcm_key", ""), Endpoint.GCM);
-
- setupXmppComponent(new JID("", env.getProperty("push_jid"), ""), env.getProperty("xmpp_host", "localhost"),
- NumberUtils.toInt(env.getProperty("xmpp_port", ""), 5347), env.getProperty("push_xmpp_password", ""));
- service.submit(() -> xmpp.startParsing());
+ 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", "");
}
@Override
- public void destroy() {
- logger.info("component destroyed");
- }
-
- public void setupXmppComponent(JID jid, String host, int port, String password) {
+ public void afterPropertiesSet() throws Exception {
try {
- socket = new Socket(host, port);
- xmpp = new StreamComponent(jid, socket.getInputStream(), socket.getOutputStream(), password);
+ socket = new Socket(xmppHost, xmppPort);
+ xmpp = new StreamComponent(new JID("", pushJid, ""), socket.getInputStream(), socket.getOutputStream(), xmppPushPassword);
xmpp.addChildParser(new JuickMessage());
xmpp.addListener((Stream.StreamListener) this);
xmpp.addListener((MessageListener) this);
- } catch (IOException e) {
- logger.error(e.getMessage(), e);
+
+ service.submit(() -> xmpp.startParsing());
+
+ logger.info("Notifications initialized");
+ } catch (Exception e) {
+ logger.error("Notifications initialization error", e);
}
}
@Override
+ public void destroy() {
+ ThreadHelper.shutdownAndAwaitTermination(service);
+
+ logger.info("component destroyed");
+ }
+
+ @Override
public void onStreamReady() {
logger.info("XMPP STREAM READY");
}
@Override
- public void onStreamFail(Exception e) {logger.error("XMPP STREAM FAIL", e);}
+ public void onStreamFail(final Exception e) {
+ logger.error("XMPP STREAM FAIL", e);
+ }
@Override
- public void onMessage(com.juick.xmpp.Message msg) {
- JuickMessage jmsg = (JuickMessage)msg.getChild(JuickMessage.XMLNS);
+ public void onMessage(final com.juick.xmpp.Message msg) {
+ JuickMessage jmsg = (JuickMessage) msg.getChild(JuickMessage.XMLNS);
boolean isPM = jmsg.getMID() == 0;
boolean isReply = jmsg.getRID() > 0;
int pmTo = 0;
@@ -125,11 +137,13 @@ public class Notifications implements DisposableBean, Stream.StreamListener, Mes
if (isPM) {
regids.addAll(rest.exchange(String.format("http://api.juick.com/notifications?type=gcm&uid=%s",
jmsg.getUser().getUID()),
- HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {}).getBody());
+ HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {
+ }).getBody());
} else {
regids.addAll(rest.exchange(String.format("http://api.juick.com/notifications?type=gcm&uid=%s&mid=%s",
jmsg.getUser().getUID(), jmsg.getMID()),
- HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {}).getBody());
+ HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {
+ }).getBody());
}
if (!regids.isEmpty()) {
@@ -157,14 +171,15 @@ public class Notifications implements DisposableBean, Stream.StreamListener, Mes
if (isPM) {
urls.addAll(rest.exchange(String.format("http://api.juick.com/notifications?type=mpns&uid=%s",
jmsg.getUser().getUID()),
- HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {}).getBody());
+ HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {
+ }).getBody());
} else {
urls.addAll(rest.exchange(String.format("http://api.juick.com/notifications?type=mpns&uid=%s&mid=%s",
jmsg.getUser().getUID(), jmsg.getMID()),
- HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {}).getBody());
+ HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {
+ }).getBody());
}
-
if (urls.isEmpty()) {
logger.info("WNS: no recipients");
} else {
@@ -203,11 +218,13 @@ public class Notifications implements DisposableBean, Stream.StreamListener, Mes
if (isPM) {
tokens.addAll(rest.exchange(String.format("http://api.juick.com/notifications?type=apns&uid=%s",
jmsg.getUser().getUID()),
- HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {}).getBody());
+ HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {
+ }).getBody());
} else {
tokens.addAll(rest.exchange(String.format("http://api.juick.com/notifications?type=apns&uid=%s&mid=%s",
jmsg.getUser().getUID(), jmsg.getMID()),
- HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {}).getBody());
+ HttpMethod.GET, null, new ParameterizedTypeReference<List<String>>() {
+ }).getBody());
}
if (!tokens.isEmpty()) {
ApnsService service = APNS.newService().withCert("/etc/juick/ios.p12", "juick")
@@ -223,10 +240,10 @@ public class Notifications implements DisposableBean, Stream.StreamListener, Mes
}
String getWnsAccessToken() throws IOException, IllegalStateException {
- if(TextUtils.isEmpty(wns_application_sip)) {
+ if (TextUtils.isEmpty(wns_application_sip)) {
throw new IllegalStateException("'wns_application_sip' is not initialized");
}
- if(TextUtils.isEmpty(wns_client_secret)) {
+ if (TextUtils.isEmpty(wns_client_secret)) {
throw new IllegalStateException("'wns_client_secret' is not initialized");
}
HttpClient client = HttpClientBuilder.create().build();
@@ -243,17 +260,17 @@ public class Notifications implements DisposableBean, Stream.StreamListener, Mes
int statusCode = response.getStatusLine().getStatusCode();
String responseContent = EntityUtils.toString(response.getEntity(), Consts.UTF_8);
JSONObject json = new JSONObject(responseContent);
- if(statusCode != 200) {
+ if (statusCode != 200) {
throw new IOException(json.opt("error") + ": " + json.opt("error_description"));
}
- String tokenType = (String)json.get("token_type");
- if(tokenType.length() >= 1) {
+ String tokenType = (String) json.get("token_type");
+ if (tokenType.length() >= 1) {
tokenType = Character.toUpperCase(tokenType.charAt(0)) + tokenType.substring(1);
}
return tokenType + " " + json.get("access_token");
}
- void sendWNS(String wnsToken, String url, String xml) throws IOException {
+ 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);
@@ -263,13 +280,13 @@ public class Notifications implements DisposableBean, Stream.StreamListener, Mes
httpPost.setEntity(entity);
HttpResponse response = client.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
- if(statusCode != 200) {
+ if (statusCode != 200) {
String headersContent = stringifyWnsHttpHeaders(response.getAllHeaders());
throw new IOException(headersContent);
}
}
- static String stringifyWnsHttpHeaders(Header[] allHeaders) {
+ static String stringifyWnsHttpHeaders(final Header[] allHeaders) {
String[] wnsHeaders = Arrays.stream(allHeaders)
.filter(x -> x.getName().startsWith("X-WNS-") || x.getName().startsWith("WWW-"))
.map(x -> x.getName() + ": " + x.getValue())
diff --git a/juick-notifications/src/main/java/com/juick/components/configuration/NotificationsAppConfiguration.java b/juick-notifications/src/main/java/com/juick/components/configuration/NotificationsAppConfiguration.java
new file mode 100644
index 000000000..1974830ad
--- /dev/null
+++ b/juick-notifications/src/main/java/com/juick/components/configuration/NotificationsAppConfiguration.java
@@ -0,0 +1,40 @@
+package com.juick.components.configuration;
+
+import com.juick.components.Notifications;
+import com.juick.configuration.DataConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.web.client.RestTemplate;
+
+import javax.inject.Inject;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Created by aalexeev on 11/12/16.
+ */
+@Configuration
+@PropertySource("classpath:juick.conf")
+@Import(DataConfiguration.class)
+public class NotificationsAppConfiguration {
+ @Inject
+ private Environment env;
+
+ @Bean
+ public RestTemplate rest() {
+ return new RestTemplate();
+ }
+
+ @Bean
+ public Notifications push() {
+ return new Notifications(env, service(), rest());
+ }
+
+ @Bean
+ public ExecutorService service() {
+ return Executors.newCachedThreadPool();
+ }
+}
diff --git a/juick-notifications/src/main/java/com/juick/components/configuration/NotificationsConfiguration.java b/juick-notifications/src/main/java/com/juick/components/configuration/NotificationsConfiguration.java
deleted file mode 100644
index 7410648a9..000000000
--- a/juick-notifications/src/main/java/com/juick/components/configuration/NotificationsConfiguration.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package com.juick.components.configuration;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
-import com.juick.components.Notifications;
-import com.mitchellbosecke.pebble.PebbleEngine;
-import com.mitchellbosecke.pebble.loader.Loader;
-import com.mitchellbosecke.pebble.loader.ServletLoader;
-import com.mitchellbosecke.pebble.spring4.PebbleViewResolver;
-import com.mitchellbosecke.pebble.spring4.extension.SpringExtension;
-import org.springframework.beans.factory.config.PlaceholderConfigurerSupport;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.PropertySource;
-import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
-import org.springframework.core.env.Environment;
-import org.springframework.http.converter.HttpMessageConverter;
-import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
-import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.servlet.ViewResolver;
-import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
-import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
-
-import javax.inject.Inject;
-import javax.servlet.ServletContext;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-/**
- * Created by vitalyster on 28.06.2016.
- */
-@Configuration
-@ComponentScan(basePackages = {"com.juick"})
-@PropertySource(value = {"classpath:juick.conf", "file:${user.home}/juick.conf"})
-public class NotificationsConfiguration extends WebMvcConfigurationSupport {
- @Inject
- Environment env;
- @Inject
- private ServletContext servletContext;
-
- @Bean
- public static PlaceholderConfigurerSupport propertySourcesPlaceholderConfigurer() {
- PlaceholderConfigurerSupport configurer = new PropertySourcesPlaceholderConfigurer();
-
- configurer.setFileEncoding("utf-8");
- configurer.setOrder(1);
- return configurer;
- }
-
- @Bean
- RestTemplate rest() {
- return new RestTemplate();
- }
-
- @Bean
- public Loader templateLoader() {
- return new ServletLoader(servletContext);
- }
-
- @Bean
- public SpringExtension springExtension() {
- return new SpringExtension();
- }
-
- @Bean
- public PebbleEngine pebbleEngine() {
- return new PebbleEngine.Builder()
- .loader(this.templateLoader())
- .extension(springExtension())
- .build();
- }
-
- @Bean
- public ViewResolver viewResolver() {
- PebbleViewResolver viewResolver = new PebbleViewResolver();
- viewResolver.setPrefix("/WEB-INF/templates/");
- viewResolver.setSuffix(".html");
- viewResolver.setPebbleEngine(pebbleEngine());
- return viewResolver;
- }
-
- @Bean
- public Notifications push() {
- return new Notifications(env, service());
- }
-
- @Bean
- public ExecutorService service() {
- return Executors.newCachedThreadPool();
- }
-
- @Override
- public RequestMappingHandlerMapping requestMappingHandlerMapping() {
- RequestMappingHandlerMapping mapping = super.requestMappingHandlerMapping();
- mapping.setUseSuffixPatternMatch(false);
- return mapping;
- }
-
- @Override
- protected void addResourceHandlers(ResourceHandlerRegistry registry) {
- registry.setOrder(0);
- registry.addResourceHandler("/scripts.js").addResourceLocations("/");
- registry.addResourceHandler("/style.css").addResourceLocations("/");
- }
-
- @Override
- protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
- Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
- .serializationInclusion(JsonInclude.Include.NON_DEFAULT)
- .serializationInclusion(JsonInclude.Include.NON_NULL)
- .serializationInclusion(JsonInclude.Include.NON_ABSENT)
- .serializationInclusion(JsonInclude.Include.NON_EMPTY);
- MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(builder.build());
- converter.getObjectMapper().registerModule(new Jdk8Module());
- converters.add(converter);
- super.configureMessageConverters(converters);
- }
-}
diff --git a/juick-notifications/src/main/java/com/juick/components/configuration/NotificationsInitializer.java b/juick-notifications/src/main/java/com/juick/components/configuration/NotificationsInitializer.java
index 417cc7fab..48ff52c26 100644
--- a/juick-notifications/src/main/java/com/juick/components/configuration/NotificationsInitializer.java
+++ b/juick-notifications/src/main/java/com/juick/components/configuration/NotificationsInitializer.java
@@ -10,14 +10,15 @@ import javax.servlet.Filter;
* Created by vt on 09/02/16.
*/
public class NotificationsInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
+
@Override
protected Class<?>[] getRootConfigClasses() {
- return new Class[]{DataConfiguration.class};
+ return new Class<?>[]{NotificationsAppConfiguration.class, DataConfiguration.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
- return new Class[]{NotificationsConfiguration.class};
+ return new Class<?>[]{NotificationsMvcConfiguration.class};
}
@Override
@@ -31,4 +32,9 @@ public class NotificationsInitializer extends AbstractAnnotationConfigDispatcher
characterEncodingFilter.setEncoding("UTF-8");
return new Filter[]{characterEncodingFilter};
}
+
+ @Override
+ protected String getServletName() {
+ return "Notifications dispatcher servlet";
+ }
}
diff --git a/juick-notifications/src/main/java/com/juick/components/configuration/NotificationsMvcConfiguration.java b/juick-notifications/src/main/java/com/juick/components/configuration/NotificationsMvcConfiguration.java
new file mode 100644
index 000000000..a0f0ad060
--- /dev/null
+++ b/juick-notifications/src/main/java/com/juick/components/configuration/NotificationsMvcConfiguration.java
@@ -0,0 +1,41 @@
+package com.juick.components.configuration;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+import java.util.List;
+
+/**
+ * Created by vitalyster on 28.06.2016.
+ */
+@Configuration
+@ComponentScan(basePackages = {"com.juick.components.controllers"})
+public class NotificationsMvcConfiguration extends WebMvcConfigurationSupport {
+
+ @Override
+ public RequestMappingHandlerMapping requestMappingHandlerMapping() {
+ RequestMappingHandlerMapping mapping = super.requestMappingHandlerMapping();
+ mapping.setUseSuffixPatternMatch(false);
+ return mapping;
+ }
+
+ @Override
+ protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+ Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
+ .serializationInclusion(JsonInclude.Include.NON_DEFAULT)
+ .serializationInclusion(JsonInclude.Include.NON_NULL)
+ .serializationInclusion(JsonInclude.Include.NON_ABSENT)
+ .serializationInclusion(JsonInclude.Include.NON_EMPTY);
+ MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(builder.build());
+ converter.getObjectMapper().registerModule(new Jdk8Module());
+ converters.add(converter);
+ super.configureMessageConverters(converters);
+ }
+}