aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexander Alexeev2016-11-12 01:34:07 +0700
committerGravatar Vitaly Takmazov2016-11-12 11:14:56 +0300
commit194a9a763c6b11d207e682b2f93de94475c473b4 (patch)
tree196317662017b716066eadfa413ecbdc7532c52d
parent7d86347a351aa5263c19cd03aa0bda4650c8bfca (diff)
extracted application configuration from Mvc configuration with application specific beans;
extracted bean initialization from constructor; force using properties;
-rw-r--r--juick-core/src/main/java/com/juick/configuration/DataConfiguration.java19
-rw-r--r--juick-core/src/main/java/com/juick/util/ThreadHelper.java36
-rw-r--r--juick-crosspost/src/main/java/com/juick/components/Crosspost.java86
-rw-r--r--juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostAppConfiguration.java37
-rw-r--r--juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostInitializer.java10
-rw-r--r--juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostMvcConfiguration.java43
-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
-rw-r--r--juick-ws/src/main/java/com/juick/ws/WebsocketComponent.java20
-rw-r--r--juick-ws/src/main/java/com/juick/ws/XMPPConnection.java152
-rw-r--r--juick-ws/src/main/java/com/juick/ws/configuration/WebsocketAppConfiguration.java54
-rw-r--r--juick-ws/src/main/java/com/juick/ws/configuration/WebsocketConfiguration.java136
-rw-r--r--juick-ws/src/main/java/com/juick/ws/configuration/WebsocketInitializer.java10
-rw-r--r--juick-ws/src/main/java/com/juick/ws/configuration/WebsocketMvcConfiguration.java (renamed from juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostConfiguration.java)48
-rw-r--r--juick-ws/src/main/java/com/juick/ws/controllers/ApiController.java (renamed from juick-ws/src/main/java/com/juick/ws/ApiController.java)5
-rw-r--r--juick-ws/src/main/java/com/juick/ws/controllers/StatusController.java (renamed from juick-ws/src/main/java/com/juick/ws/StatusController.java)6
-rw-r--r--juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferAppConfiguration.java38
-rw-r--r--juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferInitializer.java19
-rw-r--r--juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferMvcConfiguration.java33
-rw-r--r--juick-xmpp/src/main/java/com/juick/components/XMPPServer.java60
-rw-r--r--juick-xmpp/src/main/java/com/juick/components/configuration/XMPPConfiguration.java112
-rw-r--r--juick-xmpp/src/main/java/com/juick/components/configuration/XmppAppConfiguration.java38
-rw-r--r--juick-xmpp/src/main/java/com/juick/components/configuration/XmppInitializer.java (renamed from juick-xmpp/src/main/java/com/juick/components/configuration/XMPPInitializer.java)17
-rw-r--r--juick-xmpp/src/main/java/com/juick/components/configuration/XmppMvcConfiguration.java (renamed from juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferConfiguration.java)40
27 files changed, 683 insertions, 660 deletions
diff --git a/juick-core/src/main/java/com/juick/configuration/DataConfiguration.java b/juick-core/src/main/java/com/juick/configuration/DataConfiguration.java
index 62ca0f88..f31dbcdb 100644
--- a/juick-core/src/main/java/com/juick/configuration/DataConfiguration.java
+++ b/juick-core/src/main/java/com/juick/configuration/DataConfiguration.java
@@ -1,11 +1,9 @@
package com.juick.configuration;
import org.apache.commons.dbcp2.BasicDataSource;
-import org.springframework.beans.factory.config.PlaceholderConfigurerSupport;
import org.springframework.context.annotation.Bean;
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.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@@ -21,26 +19,21 @@ import javax.sql.DataSource;
*/
@Configuration
@EnableTransactionManagement
-@PropertySource(value = {"classpath:juick.conf", "file:${user.home}/juick.conf"})
+@PropertySource(value = {"classpath:juick.conf"})
public class DataConfiguration implements TransactionManagementConfigurer {
@Resource
private Environment env;
@Bean
- public static PlaceholderConfigurerSupport propertySourcesPlaceholderConfigurer() {
- PlaceholderConfigurerSupport configurer = new PropertySourcesPlaceholderConfigurer();
-
- configurer.setFileEncoding("utf-8");
- configurer.setOrder(0);
- return configurer;
- }
-
- @Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("datasource_driver", "com.mysql.jdbc.Driver"));
dataSource.setUrl(env.getProperty("datasource_url"));
+ dataSource.setUsername(env.getProperty("datasource_user", ""));
+ dataSource.setPassword(env.getProperty("datasource_password", ""));
+
+ dataSource.setValidationQuery("select 1");
return dataSource;
}
@@ -56,7 +49,7 @@ public class DataConfiguration implements TransactionManagementConfigurer {
}
@Bean
- public JdbcTemplate jdbc() {
+ public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource());
}
}
diff --git a/juick-core/src/main/java/com/juick/util/ThreadHelper.java b/juick-core/src/main/java/com/juick/util/ThreadHelper.java
new file mode 100644
index 00000000..7304d158
--- /dev/null
+++ b/juick-core/src/main/java/com/juick/util/ThreadHelper.java
@@ -0,0 +1,36 @@
+package com.juick.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by aalexeev on 11/11/16.
+ */
+public class ThreadHelper {
+ private ThreadHelper() {
+ throw new IllegalStateException();
+ }
+
+ private static Logger logger = LoggerFactory.getLogger(ThreadHelper.class);
+
+ public static void shutdownAndAwaitTermination(ExecutorService pool) {
+ pool.shutdown(); // Disable new tasks from being submitted
+ try {
+ // Wait a while for existing tasks to terminate
+ if (!pool.awaitTermination(5, TimeUnit.SECONDS)) {
+ pool.shutdownNow(); // Cancel currently executing tasks
+ // Wait a while for tasks to respond to being cancelled
+ if (!pool.awaitTermination(5, TimeUnit.SECONDS))
+ logger.error("Pool did not terminate");
+ }
+ } catch (InterruptedException ie) {
+ // (Re-)Cancel if current thread also interrupted
+ pool.shutdownNow();
+ // Preserve interrupt status
+ Thread.currentThread().interrupt();
+ }
+ }
+}
diff --git a/juick-crosspost/src/main/java/com/juick/components/Crosspost.java b/juick-crosspost/src/main/java/com/juick/components/Crosspost.java
index 35623c40..905816fd 100644
--- a/juick-crosspost/src/main/java/com/juick/components/Crosspost.java
+++ b/juick-crosspost/src/main/java/com/juick/components/Crosspost.java
@@ -18,6 +18,7 @@
package com.juick.components;
import com.juick.server.CrosspostQueries;
+import com.juick.util.ThreadHelper;
import com.juick.xmpp.JID;
import com.juick.xmpp.Message;
import com.juick.xmpp.Stream;
@@ -29,8 +30,10 @@ import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.util.Assert;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
@@ -46,36 +49,40 @@ import java.util.concurrent.ExecutorService;
/**
* @author Ugnich Anton
*/
-public class Crosspost implements DisposableBean, Stream.StreamListener, Message.MessageListener {
- public final static String TWITTERURL = "https://api.twitter.com/1.1/statuses/update.json";
- public final static String FBURL = "https://graph.facebook.com/me/feed";
- public final static String VKURL = "https://api.vk.com/method/wall.post";
+public class Crosspost implements InitializingBean, DisposableBean, Stream.StreamListener, Message.MessageListener {
+ final static String TWITTERURL = "https://api.twitter.com/1.1/statuses/update.json";
+ final static String FBURL = "https://graph.facebook.com/me/feed";
+ final static String VKURL = "https://api.vk.com/method/wall.post";
private static Logger logger = LoggerFactory.getLogger(Crosspost.class);
- JdbcTemplate jdbc;
- Stream xmpp;
- String twitter_consumer_key;
- String twitter_consumer_secret;
- ExecutorService service;
+ private final JdbcTemplate jdbc;
+ private final ExecutorService service;
+ private Stream xmpp;
+
+ private final String twitter_consumer_key;
+ private final String twitter_consumer_secret;
+ private final String crosspostJid;
+ private final String password;
+ private final int port;
+
+ public Crosspost(final Environment env, final ExecutorService service, final JdbcTemplate jdbc) {
+ Assert.notNull(env);
+ Assert.notNull(service);
+ Assert.notNull(jdbc);
- public Crosspost(Environment env, ExecutorService service, JdbcTemplate jdbc) {
this.service = service;
this.jdbc = jdbc;
- logger.info("component initialized");
- try {
- twitter_consumer_key = env.getProperty("twitter_consumer_key", "");
- twitter_consumer_secret = env.getProperty("twitter_consumer_secret", "");
- setupXmppComponent(env.getProperty("crosspost_jid", "crosspost.juick.local"),
- env.getProperty("xmpp_password", ""), NumberUtils.toInt(env.getProperty("xmpp_port", ""), 5347));
- service.submit(() -> xmpp.startParsing());
- } catch (Exception e) {
- logger.error("crosspost exception", e);
- }
+ twitter_consumer_key = env.getProperty("twitter_consumer_key", "");
+ twitter_consumer_secret = env.getProperty("twitter_consumer_secret", "");
+
+ crosspostJid = env.getProperty("crosspost_jid", "crosspost.juick.local");
+ password = env.getProperty("xmpp_password", "");
+ port = NumberUtils.toInt(env.getProperty("xmpp_port"), 5347);
}
- public static String percentEncode(String s) {
+ public static String percentEncode(final String s) {
String ret = "";
try {
ret = URLEncoder.encode(s, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
@@ -85,23 +92,30 @@ public class Crosspost implements DisposableBean, Stream.StreamListener, Message
}
@Override
- public void destroy() {
- logger.info("component destroyed");
- }
-
- public void setupXmppComponent(String jid, String password, int port) {
+ public void afterPropertiesSet() throws Exception {
try {
Socket socket = new Socket("localhost", port);
- xmpp = new StreamComponent(new JID(jid), socket.getInputStream(), socket.getOutputStream(), password);
+ xmpp = new StreamComponent(new JID(crosspostJid), socket.getInputStream(), socket.getOutputStream(), password);
xmpp.addChildParser(new JuickMessage());
xmpp.addListener((Stream.StreamListener) this);
xmpp.addListener((Message.MessageListener) this);
- } catch (IOException e) {
- logger.error(e.getMessage(), e);
+
+ service.submit(() -> xmpp.startParsing());
+
+ logger.info("Crosspost initialized");
+ } catch (Exception e) {
+ logger.error("Crosspost initialization exception", e);
}
}
@Override
+ public void destroy() throws Exception {
+ ThreadHelper.shutdownAndAwaitTermination(service);
+
+ logger.info("Crosspost destroyed");
+ }
+
+ @Override
public void onStreamReady() {
logger.info("XMPP STREAM READY");
}
@@ -112,7 +126,7 @@ public class Crosspost implements DisposableBean, Stream.StreamListener, Message
}
@Override
- public void onMessage(com.juick.xmpp.Message msg) {
+ public void onMessage(final com.juick.xmpp.Message msg) {
JuickMessage jmsg = (JuickMessage) msg.getChild(JuickMessage.XMLNS);
if (msg.to != null && msg.to.Username != null && jmsg != null && jmsg.getRID() == 0) {
if (msg.to.Username.equals("twitter")) {
@@ -125,7 +139,7 @@ public class Crosspost implements DisposableBean, Stream.StreamListener, Message
}
}
- public boolean facebookPost(com.juick.Message jmsg) {
+ public boolean facebookPost(final com.juick.Message jmsg) {
String token = CrosspostQueries.getFacebookToken(jdbc, jmsg.getUser().getUID()).orElse("");
if (token.isEmpty()) {
return false;
@@ -167,7 +181,7 @@ public class Crosspost implements DisposableBean, Stream.StreamListener, Message
return ret;
}
- public boolean vkontaktePost(com.juick.Message jmsg) {
+ public boolean vkontaktePost(final com.juick.Message jmsg) {
Pair<String, String> tokens = CrosspostQueries.getVKTokens(jdbc, jmsg.getUser().getUID()).orElse(Pair.of("", ""));
if (tokens.getLeft().isEmpty() || tokens.getRight().isEmpty()) {
return false;
@@ -204,7 +218,7 @@ public class Crosspost implements DisposableBean, Stream.StreamListener, Message
return ret;
}
- public boolean twitterPost(com.juick.Message jmsg) {
+ public boolean twitterPost(final com.juick.Message jmsg) {
Pair<String, String> tokens = CrosspostQueries.getTwitterTokens(jdbc, jmsg.getUser().getUID()).orElse(Pair.of("", ""));
if (tokens.getLeft().isEmpty() || tokens.getRight().isEmpty()) {
return false;
@@ -259,7 +273,7 @@ public class Crosspost implements DisposableBean, Stream.StreamListener, Message
return ret;
}
- public String twitterSignature(String status, String nonce, String timestamp, String token, String token_secret) {
+ public String twitterSignature(final String status, final String nonce, final String timestamp, final String token, final String token_secret) {
try {
// ALPHABET-SORTED
String params = "oauth_consumer_key=" + twitter_consumer_key
@@ -285,7 +299,7 @@ public class Crosspost implements DisposableBean, Stream.StreamListener, Message
return null;
}
- public String streamToString(InputStream is) {
+ public String streamToString(final InputStream is) {
try {
BufferedReader buf = new BufferedReader(new InputStreamReader(is));
StringBuilder str = new StringBuilder();
@@ -301,7 +315,7 @@ public class Crosspost implements DisposableBean, Stream.StreamListener, Message
return null;
}
- public String getMessageHashTags(com.juick.Message jmsg) {
+ public String getMessageHashTags(final com.juick.Message jmsg) {
String hashtags = "";
for (int i = 0; i < jmsg.Tags.size(); i++) {
hashtags += "#" + jmsg.Tags.get(i) + " ";
diff --git a/juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostAppConfiguration.java b/juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostAppConfiguration.java
new file mode 100644
index 00000000..a7787b26
--- /dev/null
+++ b/juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostAppConfiguration.java
@@ -0,0 +1,37 @@
+package com.juick.components.configuration;
+
+import com.juick.components.Crosspost;
+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.jdbc.core.JdbcTemplate;
+
+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 CrosspostAppConfiguration {
+ @Inject
+ private Environment env;
+ @Inject
+ private JdbcTemplate jdbcTemplate;
+
+ @Bean
+ public Crosspost crosspost() {
+ return new Crosspost(env, service(), jdbcTemplate);
+ }
+
+ @Bean
+ public ExecutorService service() {
+ return Executors.newCachedThreadPool();
+ }
+}
diff --git a/juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostInitializer.java b/juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostInitializer.java
index 0768f834..baedfa29 100644
--- a/juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostInitializer.java
+++ b/juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostInitializer.java
@@ -10,14 +10,15 @@ import javax.servlet.Filter;
* Created by vt on 09/02/16.
*/
public class CrosspostInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
+
@Override
protected Class<?>[] getRootConfigClasses() {
- return new Class<?>[]{DataConfiguration.class};
+ return new Class<?>[]{CrosspostAppConfiguration.class, DataConfiguration.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
- return new Class<?>[]{CrosspostConfiguration.class};
+ return new Class<?>[]{CrosspostMvcConfiguration.class};
}
@Override
@@ -32,4 +33,9 @@ public class CrosspostInitializer extends AbstractAnnotationConfigDispatcherServ
return new Filter[]{characterEncodingFilter};
}
+
+ @Override
+ protected String getServletName() {
+ return "Crosspost dispatcher servlet";
+ }
}
diff --git a/juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostMvcConfiguration.java b/juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostMvcConfiguration.java
new file mode 100644
index 00000000..619c3d78
--- /dev/null
+++ b/juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostMvcConfiguration.java
@@ -0,0 +1,43 @@
+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 CrosspostMvcConfiguration 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);
+ }
+}
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 12993418..b7e6b2b8 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 00000000..1974830a
--- /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 7410648a..00000000
--- 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 417cc7fa..48ff52c2 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 00000000..a0f0ad06
--- /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);
+ }
+}
diff --git a/juick-ws/src/main/java/com/juick/ws/WebsocketComponent.java b/juick-ws/src/main/java/com/juick/ws/WebsocketComponent.java
index 2ab3a94c..4ce230a4 100644
--- a/juick-ws/src/main/java/com/juick/ws/WebsocketComponent.java
+++ b/juick-ws/src/main/java/com/juick/ws/WebsocketComponent.java
@@ -9,6 +9,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.util.Assert;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
@@ -24,13 +25,17 @@ import java.util.List;
* Created by vitalyster on 28.06.2016.
*/
public class WebsocketComponent extends TextWebSocketHandler {
+ private static final Logger logger = LoggerFactory.getLogger(WebsocketComponent.class);
- @Inject
- JdbcTemplate jdbc;
+ private JdbcTemplate jdbc;
- private static final Logger logger = LoggerFactory.getLogger(WebsocketComponent.class);
+ private final List<SocketSubscribed> clients = Collections.synchronizedList(new ArrayList<SocketSubscribed>());
- final List<SocketSubscribed> clients = Collections.synchronizedList(new ArrayList<SocketSubscribed>());
+
+ public WebsocketComponent(JdbcTemplate jdbc) {
+ Assert.notNull(jdbc);
+ this.jdbc = jdbc;
+ }
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
@@ -102,6 +107,7 @@ public class WebsocketComponent extends TextWebSocketHandler {
}
}
}
+
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
synchronized (clients) {
@@ -116,8 +122,12 @@ public class WebsocketComponent extends TextWebSocketHandler {
}
}
- class SocketSubscribed {
+ public List<SocketSubscribed> getClients() {
+ return clients;
+ }
+
+ class SocketSubscribed {
WebSocketSession session;
String clientName;
User visitor;
diff --git a/juick-ws/src/main/java/com/juick/ws/XMPPConnection.java b/juick-ws/src/main/java/com/juick/ws/XMPPConnection.java
index 9e793a44..04ea5378 100644
--- a/juick-ws/src/main/java/com/juick/ws/XMPPConnection.java
+++ b/juick-ws/src/main/java/com/juick/ws/XMPPConnection.java
@@ -4,6 +4,7 @@ import com.juick.User;
import com.juick.json.MessageSerializer;
import com.juick.server.MessagesQueries;
import com.juick.server.SubscriptionsQueries;
+import com.juick.util.ThreadHelper;
import com.juick.xmpp.JID;
import com.juick.xmpp.Message;
import com.juick.xmpp.Stream;
@@ -12,12 +13,13 @@ import com.juick.xmpp.extensions.JuickMessage;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.stereotype.Component;
+import org.springframework.util.Assert;
import org.springframework.web.socket.TextMessage;
-import javax.inject.Inject;
import java.io.IOException;
import java.net.Socket;
import java.util.List;
@@ -25,52 +27,76 @@ import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
/**
- *
* @author ugnich
*/
-@Component
-public class XMPPConnection implements Stream.StreamListener, Message.MessageListener {
+public class XMPPConnection implements InitializingBean, DisposableBean, Stream.StreamListener, Message.MessageListener {
private static final Logger logger = LoggerFactory.getLogger(XMPPConnection.class);
- @Inject
- JdbcTemplate jdbc;
- ExecutorService service;
- Stream xmpp;
- String xmppPassword;
- MessageSerializer ms;
- @Inject
- WebsocketComponent wsHandler;
-
- @Inject
- public XMPPConnection(Environment env, ExecutorService service) {
+ private final JdbcTemplate jdbc;
+ private final ExecutorService service;
+ private final WebsocketComponent wsHandler;
+ private final String xmppPassword;
+ private final MessageSerializer ms;
+ private final int xmppPort;
+ private final String wsJid;
+
+ private Stream xmpp;
+
+
+ public XMPPConnection(
+ final Environment env, final ExecutorService service, final WebsocketComponent wsHandler, final JdbcTemplate jdbc) {
+ Assert.notNull(env);
+ Assert.notNull(service);
+ Assert.notNull(wsHandler);
+ Assert.notNull(jdbc);
+
this.service = service;
+ this.wsHandler = wsHandler;
+ this.jdbc = jdbc;
+
xmppPassword = env.getProperty("xmpp_password");
+ xmppPort = NumberUtils.toInt(env.getProperty("xmpp_port"), 5347);
+ wsJid = env.getProperty("ws_jid", "ws.juick.local");
+
ms = new MessageSerializer();
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
try {
- Socket socket = new Socket("localhost", NumberUtils.toInt(env.getProperty("xmpp_port", ""), 5347));
- xmpp = new StreamComponent(new JID(env.getProperty("ws_jid", "ws.juick.local")), socket.getInputStream(), socket.getOutputStream(), xmppPassword);
+ Socket socket = new Socket("localhost", xmppPort);
+ xmpp = new StreamComponent(new JID(wsJid), socket.getInputStream(), socket.getOutputStream(), xmppPassword);
xmpp.addChildParser(new JuickMessage());
xmpp.addListener((Stream.StreamListener) this);
xmpp.addListener((Message.MessageListener) this);
+
service.submit(() -> xmpp.startParsing());
+
+ logger.info("XMPPConnection initialized");
} catch (IOException e) {
- logger.error("XMPPConnection error", e);
+ logger.error("XMPPConnection initialization error", e);
}
}
+ @Override
+ public void destroy() throws Exception {
+ ThreadHelper.shutdownAndAwaitTermination(service);
+
+ logger.info("XMPPConnection destroyed");
+ }
@Override
public void onStreamReady() {
- logger.info("XMPP stream ready");
+ logger.info("XMPP stream ready");
}
@Override
- public void onStreamFail(Exception ex) {
+ public void onStreamFail(final Exception ex) {
logger.error("XMPP stream failed", ex);
}
@Override
- public void onMessage(com.juick.xmpp.Message msg) {
+ public void onMessage(final com.juick.xmpp.Message msg) {
JuickMessage jmsg = (JuickMessage) msg.getChild(JuickMessage.XMLNS);
if (jmsg != null) {
logger.info("got jmsg: " + ms.serialize(jmsg).toString());
@@ -95,10 +121,10 @@ public class XMPPConnection implements Stream.StreamListener, Message.MessageLis
MessageSerializer messageSerializer = new MessageSerializer();
- private void onJuickPM(int uid_to, com.juick.Message jmsg) {
+ private void onJuickPM(final int uid_to, final com.juick.Message jmsg) {
String json = messageSerializer.serialize(jmsg).toString();
- synchronized (wsHandler.clients) {
- wsHandler.clients.stream().filter(c -> !c.legacy && c.visitor.getUID() == uid_to).forEach(c -> {
+ synchronized (wsHandler.getClients()) {
+ wsHandler.getClients().stream().filter(c -> !c.legacy && c.visitor.getUID() == uid_to).forEach(c -> {
try {
logger.info("sending pm to " + c.visitor.getUID());
c.session.sendMessage(new TextMessage(json));
@@ -109,62 +135,62 @@ public class XMPPConnection implements Stream.StreamListener, Message.MessageLis
}
}
- private void onJuickMessagePost(com.juick.Message jmsg) {
+ private void onJuickMessagePost(final com.juick.Message jmsg) {
String json = messageSerializer.serialize(jmsg).toString();
List<Integer> uids = SubscriptionsQueries.getSubscribedUsers(jdbc, jmsg.getUser().getUID(), jmsg.getMID())
.stream().map(User::getUID).collect(Collectors.toList());
- synchronized (wsHandler.clients) {
- wsHandler.clients.stream().filter(c ->
+ synchronized (wsHandler.getClients()) {
+ wsHandler.getClients().stream().filter(c ->
(!c.legacy && c.visitor.getUID() == 0) // anonymous users
- || (!c.legacy && uids.contains(c.visitor.getUID()))) // subscriptions
+ || (!c.legacy && uids.contains(c.visitor.getUID()))) // subscriptions
.forEach(c -> {
- try {
- logger.info("sending message to " + c.visitor.getUID());
- c.session.sendMessage(new TextMessage(json));
- } catch (IOException e) {
- logger.warn("ws error", e);
- }
- });
- wsHandler.clients.stream().filter(c ->
+ try {
+ logger.info("sending message to " + c.visitor.getUID());
+ c.session.sendMessage(new TextMessage(json));
+ } catch (IOException e) {
+ logger.warn("ws error", e);
+ }
+ });
+ wsHandler.getClients().stream().filter(c ->
c.legacy && c.allMessages) // legacy all posts
.forEach(c -> {
- try {
- logger.info("sending message to legacy client " + c.visitor.getUID());
- c.session.sendMessage(new TextMessage(json));
- } catch (IOException e) {
- logger.warn("ws error", e);
- }
- });
+ try {
+ logger.info("sending message to legacy client " + c.visitor.getUID());
+ c.session.sendMessage(new TextMessage(json));
+ } catch (IOException e) {
+ logger.warn("ws error", e);
+ }
+ });
}
}
- private void onJuickMessageReply(com.juick.Message jmsg) {
+ private void onJuickMessageReply(final com.juick.Message jmsg) {
String json = messageSerializer.serialize(jmsg).toString();
List<Integer> threadUsers =
SubscriptionsQueries.getUsersSubscribedToComments(jdbc, jmsg.getMID(), jmsg.getUser().getUID())
.stream().map(User::getUID).collect(Collectors.toList());
- synchronized (wsHandler.clients) {
- wsHandler.clients.stream().filter(c ->
+ synchronized (wsHandler.getClients()) {
+ wsHandler.getClients().stream().filter(c ->
(!c.legacy && c.visitor.getUID() == 0) // anonymous users
- || (!c.legacy && threadUsers.contains(c.visitor.getUID()))) // subscriptions
+ || (!c.legacy && threadUsers.contains(c.visitor.getUID()))) // subscriptions
.forEach(c -> {
- try {
- logger.info("sending reply to " + c.visitor.getUID());
- c.session.sendMessage(new TextMessage(json));
- } catch (IOException e) {
- logger.warn("ws error", e);
- }
- });
- wsHandler.clients.stream().filter(c ->
+ try {
+ logger.info("sending reply to " + c.visitor.getUID());
+ c.session.sendMessage(new TextMessage(json));
+ } catch (IOException e) {
+ logger.warn("ws error", e);
+ }
+ });
+ wsHandler.getClients().stream().filter(c ->
(c.legacy && c.allReplies) || (c.legacy && c.MID == jmsg.getMID())) // legacy replies
.forEach(c -> {
- try {
- logger.info("sending reply to legacy client " + c.visitor.getUID());
- c.session.sendMessage(new TextMessage(json));
- } catch (IOException e) {
- logger.warn("ws error", e);
- }
- });
+ try {
+ logger.info("sending reply to legacy client " + c.visitor.getUID());
+ c.session.sendMessage(new TextMessage(json));
+ } catch (IOException e) {
+ logger.warn("ws error", e);
+ }
+ });
}
}
}
diff --git a/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketAppConfiguration.java b/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketAppConfiguration.java
new file mode 100644
index 00000000..9e2e4f6f
--- /dev/null
+++ b/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketAppConfiguration.java
@@ -0,0 +1,54 @@
+package com.juick.ws.configuration;
+
+import com.juick.configuration.DataConfiguration;
+import com.juick.ws.WebsocketComponent;
+import com.juick.ws.XMPPConnection;
+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.jdbc.core.JdbcTemplate;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.ServletWebSocketHandlerRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+
+import javax.inject.Inject;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Created by aalexeev on 11/12/16.
+ */
+@Configuration
+@EnableWebSocket
+@PropertySource("classpath:juick.conf")
+@Import(DataConfiguration.class)
+public class WebsocketAppConfiguration implements WebSocketConfigurer {
+ @Inject
+ private Environment env;
+ @Inject
+ private JdbcTemplate jdbc;
+
+ @Bean
+ public WebsocketComponent wsHandler() {
+ return new WebsocketComponent(jdbc);
+ }
+
+ @Bean
+ public XMPPConnection ws() {
+ return new XMPPConnection(env, service(), wsHandler(), jdbc);
+ }
+
+ @Bean
+ public ExecutorService service() {
+ return Executors.newCachedThreadPool();
+ }
+
+ @Override
+ public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
+ ((ServletWebSocketHandlerRegistry) registry).setOrder(2);
+ registry.addHandler(wsHandler(), "/**").setAllowedOrigins("*");
+ }
+}
diff --git a/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketConfiguration.java b/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketConfiguration.java
deleted file mode 100644
index 0a2a91fa..00000000
--- a/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketConfiguration.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package com.juick.ws.configuration;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
-import com.juick.ws.WebsocketComponent;
-import com.juick.ws.XMPPConnection;
-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.jdbc.core.JdbcTemplate;
-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 org.springframework.web.socket.config.annotation.EnableWebSocket;
-import org.springframework.web.socket.config.annotation.ServletWebSocketHandlerRegistry;
-import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
-import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
-
-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
-@EnableWebSocket
-@ComponentScan(basePackages = {"com.juick"})
-@PropertySource(value = {"classpath:juick.conf", "file:${user.home}/juick.conf"})
-public class WebsocketConfiguration extends WebMvcConfigurationSupport implements WebSocketConfigurer {
- @Inject
- private Environment env;
- @Inject
- private JdbcTemplate jdbc;
- @Inject
- private ServletContext servletContext;
-
- @Bean
- public static PlaceholderConfigurerSupport propertySourcesPlaceholderConfigurer() {
- PlaceholderConfigurerSupport configurer = new PropertySourcesPlaceholderConfigurer();
-
- configurer.setFileEncoding("utf-8");
- configurer.setOrder(1);
- return configurer;
- }
-
- @Bean
- public WebsocketComponent wsHandler() {
- return new WebsocketComponent();
- }
-
- @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 XMPPConnection ws() {
- return new XMPPConnection(env, service());
- }
-
- @Bean
- public ExecutorService service() {
- return Executors.newCachedThreadPool();
- }
-
- @Override
- public RequestMappingHandlerMapping requestMappingHandlerMapping() {
- RequestMappingHandlerMapping mapping = super.requestMappingHandlerMapping();
- mapping.setUseSuffixPatternMatch(false);
- return mapping;
- }
-
- @Override
- public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
- ((ServletWebSocketHandlerRegistry) registry).setOrder(2);
- registry.addHandler(wsHandler(), "/**").setAllowedOrigins("*");
- }
-
- @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-ws/src/main/java/com/juick/ws/configuration/WebsocketInitializer.java b/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketInitializer.java
index 4829710f..d4e797ad 100644
--- a/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketInitializer.java
+++ b/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketInitializer.java
@@ -10,14 +10,15 @@ import javax.servlet.Filter;
* Created by vt on 09/02/16.
*/
public class WebsocketInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
+
@Override
protected Class<?>[] getRootConfigClasses() {
- return new Class[]{DataConfiguration.class};
+ return new Class<?>[]{WebsocketAppConfiguration.class, DataConfiguration.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
- return new Class[]{WebsocketConfiguration.class};
+ return new Class<?>[]{WebsocketMvcConfiguration.class};
}
@Override
@@ -31,4 +32,9 @@ public class WebsocketInitializer extends AbstractAnnotationConfigDispatcherServ
characterEncodingFilter.setEncoding("UTF-8");
return new Filter[]{characterEncodingFilter};
}
+
+ @Override
+ protected String getServletName() {
+ return "Web socket dispather servlet";
+ }
}
diff --git a/juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostConfiguration.java b/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketMvcConfiguration.java
index 8ae511c4..a8a88dcc 100644
--- a/juick-crosspost/src/main/java/com/juick/components/configuration/CrosspostConfiguration.java
+++ b/juick-ws/src/main/java/com/juick/ws/configuration/WebsocketMvcConfiguration.java
@@ -1,61 +1,34 @@
-package com.juick.components.configuration;
+package com.juick.ws.configuration;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
-import com.juick.components.Crosspost;
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.jdbc.core.JdbcTemplate;
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 CrosspostConfiguration extends WebMvcConfigurationSupport {
- @Inject
- private Environment env;
- @Inject
- private ServletContext servletContext;
- @Inject
- private JdbcTemplate jdbc;
-
- @Bean
- public static PlaceholderConfigurerSupport propertySourcesPlaceholderConfigurer() {
- PlaceholderConfigurerSupport configurer = new PropertySourcesPlaceholderConfigurer();
-
- configurer.setFileEncoding("utf-8");
- configurer.setOrder(1);
- return configurer;
- }
-
+@ComponentScan(basePackages = {"com.juick.ws.controllers"})
+public class WebsocketMvcConfiguration extends WebMvcConfigurationSupport {
@Bean
public Loader templateLoader() {
- return new ServletLoader(servletContext);
+ return new ServletLoader(getServletContext());
}
@Bean
@@ -77,20 +50,9 @@ public class CrosspostConfiguration extends WebMvcConfigurationSupport {
viewResolver.setPrefix("/WEB-INF/templates/");
viewResolver.setSuffix(".html");
viewResolver.setPebbleEngine(pebbleEngine());
-
return viewResolver;
}
- @Bean
- public Crosspost crosspost() {
- return new Crosspost(env, service(), jdbc);
- }
-
- @Bean
- public ExecutorService service() {
- return Executors.newCachedThreadPool();
- }
-
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping mapping = super.requestMappingHandlerMapping();
@@ -112,11 +74,9 @@ public class CrosspostConfiguration extends WebMvcConfigurationSupport {
.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-ws/src/main/java/com/juick/ws/ApiController.java b/juick-ws/src/main/java/com/juick/ws/controllers/ApiController.java
index 5203de57..2f57b0b6 100644
--- a/juick-ws/src/main/java/com/juick/ws/ApiController.java
+++ b/juick-ws/src/main/java/com/juick/ws/controllers/ApiController.java
@@ -1,6 +1,7 @@
-package com.juick.ws;
+package com.juick.ws.controllers;
import com.juick.server.helpers.Status;
+import com.juick.ws.WebsocketComponent;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@@ -19,6 +20,6 @@ public class ApiController {
@RequestMapping(value = "/api/status", method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Status status() {
- return new Status(String.valueOf(wsHandler.clients.size()));
+ return new Status(String.valueOf(wsHandler.getClients().size()));
}
}
diff --git a/juick-ws/src/main/java/com/juick/ws/StatusController.java b/juick-ws/src/main/java/com/juick/ws/controllers/StatusController.java
index f7e80106..2fe55eeb 100644
--- a/juick-ws/src/main/java/com/juick/ws/StatusController.java
+++ b/juick-ws/src/main/java/com/juick/ws/controllers/StatusController.java
@@ -1,5 +1,7 @@
-package com.juick.ws;
+package com.juick.ws.controllers;
+import com.juick.ws.WebsocketComponent;
+import com.juick.ws.XMPPConnection;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@@ -22,7 +24,7 @@ public class StatusController {
@RequestMapping(method = RequestMethod.GET, headers = "Connection!=upgrade", value = "/")
public ModelAndView status() {
ModelAndView modelAndView = new ModelAndView();
- modelAndView.addObject("clients", wsHandler.clients.size());
+ modelAndView.addObject("clients", wsHandler.getClients().size());
modelAndView.setViewName("index");
return modelAndView;
}
diff --git a/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferAppConfiguration.java b/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferAppConfiguration.java
new file mode 100644
index 00000000..88579328
--- /dev/null
+++ b/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferAppConfiguration.java
@@ -0,0 +1,38 @@
+package com.juick.components.configuration;
+
+import com.juick.components.XMPPFTServer;
+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.jdbc.core.JdbcTemplate;
+
+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 FileTransferAppConfiguration {
+ @Inject
+ private Environment env;
+ @Inject
+ private JdbcTemplate jdbc;
+
+ @Bean
+ public XMPPFTServer xmpp() {
+ return new XMPPFTServer(env);
+ }
+
+ @Bean
+ public ExecutorService service() {
+ return Executors.newCachedThreadPool();
+ }
+
+}
diff --git a/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferInitializer.java b/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferInitializer.java
index db514e21..bf0e7257 100644
--- a/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferInitializer.java
+++ b/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferInitializer.java
@@ -1,4 +1,6 @@
package com.juick.components.configuration;
+
+import com.juick.configuration.DataConfiguration;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
@@ -8,26 +10,31 @@ import javax.servlet.Filter;
* Created by vt on 09/02/16.
*/
public class FileTransferInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
+
@Override
protected Class<?>[] getRootConfigClasses() {
- return new Class[] {FileTransferConfiguration.class};
+ return new Class<?>[]{FileTransferAppConfiguration.class, DataConfiguration.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
- return null;
+ return new Class<?>[]{FileTransferMvcConfiguration.class};
}
@Override
protected String[] getServletMappings() {
- return new String[] {
- "/"
- };
+ return new String[]{"/"};
}
+
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
- return new Filter[] { characterEncodingFilter};
+ return new Filter[]{characterEncodingFilter};
+ }
+
+ @Override
+ protected String getServletName() {
+ return "File transfer dispantcher servlet";
}
}
diff --git a/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferMvcConfiguration.java b/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferMvcConfiguration.java
new file mode 100644
index 00000000..9500f4e6
--- /dev/null
+++ b/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferMvcConfiguration.java
@@ -0,0 +1,33 @@
+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 java.util.List;
+
+/**
+ * Created by vitalyster on 28.06.2016.
+ */
+@Configuration
+@ComponentScan(basePackages = {"com.juick.components.controllers"})
+public class FileTransferMvcConfiguration extends WebMvcConfigurationSupport {
+
+ @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-xmpp/src/main/java/com/juick/components/XMPPServer.java b/juick-xmpp/src/main/java/com/juick/components/XMPPServer.java
index 463d8c2a..e26e0a1e 100644
--- a/juick-xmpp/src/main/java/com/juick/components/XMPPServer.java
+++ b/juick-xmpp/src/main/java/com/juick/components/XMPPServer.java
@@ -1,7 +1,10 @@
package com.juick.components;
import com.juick.components.s2s.*;
-import com.juick.xmpp.*;
+import com.juick.util.ThreadHelper;
+import com.juick.xmpp.JID;
+import com.juick.xmpp.Stanza;
+import com.juick.xmpp.StanzaChild;
import com.juick.xmpp.extensions.JuickMessage;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
@@ -23,11 +26,9 @@ import java.util.*;
import java.util.concurrent.ExecutorService;
/**
- *
* @author ugnich
*/
public class XMPPServer implements DisposableBean {
-
private static final Logger logger = LoggerFactory.getLogger(XMPPServer.class);
public ExecutorService service;
@@ -39,15 +40,19 @@ public class XMPPServer implements DisposableBean {
public String keystorePassword;
public List<String> brokenSSLhosts;
public List<String> bannedHosts;
+
private final List<ConnectionIn> inConnections = Collections.synchronizedList(new ArrayList<>());
private final List<ConnectionOut> outConnections = Collections.synchronizedList(new ArrayList<>());
private final List<CacheEntry> outCache = Collections.synchronizedList(new ArrayList<>());
+
public JdbcTemplate jdbc;
final public HashMap<String, StanzaChild> childParsers = new HashMap<>();
+
public XMPPServer(Environment env, ExecutorService service, JdbcTemplate jdbc) {
this.service = service;
this.jdbc = jdbc;
+
logger.info("component initialized");
try {
HOSTNAME = env.getProperty("hostname");
@@ -64,7 +69,9 @@ public class XMPPServer implements DisposableBean {
childParsers.put(JuickMessage.XMLNS, new JuickMessage());
router = new ConnectionRouter(this, componentName, componentPort, env.getProperty("xmpp_password"));
+
service.submit(router);
+
service.submit(() -> {
final ServerSocket listener = new ServerSocket(s2sPort);
logger.info("s2s listener ready");
@@ -79,6 +86,7 @@ public class XMPPServer implements DisposableBean {
}
}
});
+
service.submit(new CleaningUp(this));
} catch (Exception e) {
@@ -86,6 +94,29 @@ public class XMPPServer implements DisposableBean {
}
}
+ @Override
+ public void destroy() throws Exception {
+ synchronized (getOutConnections()) {
+ for (Iterator<ConnectionOut> i = getOutConnections().iterator(); i.hasNext(); ) {
+ ConnectionOut c = i.next();
+ c.closeConnection();
+ i.remove();
+ }
+ }
+
+ synchronized (getInConnections()) {
+ for (Iterator<ConnectionIn> i = getInConnections().iterator(); i.hasNext(); ) {
+ ConnectionIn c = i.next();
+ c.closeConnection();
+ i.remove();
+ }
+ }
+
+ ThreadHelper.shutdownAndAwaitTermination(service);
+
+ logger.info("Xmpp server destroyed");
+ }
+
public void addConnectionIn(ConnectionIn c) {
synchronized (getInConnections()) {
getInConnections().add(c);
@@ -113,7 +144,7 @@ public class XMPPServer implements DisposableBean {
public String getFromCache(String hostname) {
CacheEntry ret = null;
synchronized (getOutCache()) {
- for (Iterator<CacheEntry> i = getOutCache().iterator(); i.hasNext();) {
+ for (Iterator<CacheEntry> i = getOutCache().iterator(); i.hasNext(); ) {
CacheEntry c = i.next();
if (c.hostname != null && c.hostname.equals(hostname)) {
ret = c;
@@ -202,27 +233,6 @@ public class XMPPServer implements DisposableBean {
}
}
- @Override
- public void destroy() {
- synchronized (getOutConnections()) {
- for (Iterator<ConnectionOut> i = getOutConnections().iterator(); i.hasNext();) {
- ConnectionOut c = i.next();
- c.closeConnection();
- i.remove();
- }
- }
-
- synchronized (getInConnections()) {
- for (Iterator<ConnectionIn> i = getInConnections().iterator(); i.hasNext();) {
- ConnectionIn c = i.next();
- c.closeConnection();
- i.remove();
- }
- }
- service.shutdown();
- logger.info("component destroyed");
- }
-
public ConnectionRouter getRouter() {
return router;
}
diff --git a/juick-xmpp/src/main/java/com/juick/components/configuration/XMPPConfiguration.java b/juick-xmpp/src/main/java/com/juick/components/configuration/XMPPConfiguration.java
deleted file mode 100644
index 13ac2a9d..00000000
--- a/juick-xmpp/src/main/java/com/juick/components/configuration/XMPPConfiguration.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package com.juick.components.configuration;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
-import com.juick.components.XMPPServer;
-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.jdbc.core.JdbcTemplate;
-import org.springframework.web.servlet.ViewResolver;
-import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
-
-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 XMPPConfiguration extends WebMvcConfigurationSupport {
- @Inject
- private Environment env;
- @Inject
- private JdbcTemplate jdbc;
-
- @Inject
- private ServletContext servletContext;
-
- @Bean
- public static PlaceholderConfigurerSupport propertySourcesPlaceholderConfigurer() {
- PlaceholderConfigurerSupport configurer = new PropertySourcesPlaceholderConfigurer();
-
- configurer.setFileEncoding("utf-8");
- configurer.setOrder(1);
- return configurer;
- }
-
- @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 XMPPServer xmpp() {
- return new XMPPServer(env, service(), jdbc);
- }
-
- @Bean
- public ExecutorService service() {
- return Executors.newCachedThreadPool();
- }
-
- @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-xmpp/src/main/java/com/juick/components/configuration/XmppAppConfiguration.java b/juick-xmpp/src/main/java/com/juick/components/configuration/XmppAppConfiguration.java
new file mode 100644
index 00000000..eb3dd726
--- /dev/null
+++ b/juick-xmpp/src/main/java/com/juick/components/configuration/XmppAppConfiguration.java
@@ -0,0 +1,38 @@
+package com.juick.components.configuration;
+
+/**
+ * Created by aalexeev on 11/12/16.
+ */
+
+import com.juick.components.XMPPServer;
+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.jdbc.core.JdbcTemplate;
+
+import javax.inject.Inject;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Configuration
+@PropertySource("classpath:juick.conf")
+@Import(DataConfiguration.class)
+public class XmppAppConfiguration {
+ @Inject
+ private Environment env;
+ @Inject
+ private JdbcTemplate jdbc;
+
+ @Bean
+ public XMPPServer xmpp() {
+ return new XMPPServer(env, service(), jdbc);
+ }
+
+ @Bean
+ public ExecutorService service() {
+ return Executors.newCachedThreadPool();
+ }
+}
diff --git a/juick-xmpp/src/main/java/com/juick/components/configuration/XMPPInitializer.java b/juick-xmpp/src/main/java/com/juick/components/configuration/XmppInitializer.java
index 3942f889..89dd69e1 100644
--- a/juick-xmpp/src/main/java/com/juick/components/configuration/XMPPInitializer.java
+++ b/juick-xmpp/src/main/java/com/juick/components/configuration/XmppInitializer.java
@@ -9,28 +9,33 @@ import javax.servlet.Filter;
/**
* Created by vt on 09/02/16.
*/
-public class XMPPInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
+public class XmppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
+
@Override
protected Class<?>[] getRootConfigClasses() {
- return new Class[]{DataConfiguration.class};
+ return new Class<?>[]{XmppAppConfiguration.class, DataConfiguration.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
- return new Class[]{XMPPConfiguration.class};
+ return new Class<?>[]{XmppMvcConfiguration.class};
}
@Override
protected String[] getServletMappings() {
- return new String[]{
- "/"
- };
+ return new String[]{"/"};
}
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
+
return new Filter[]{characterEncodingFilter};
}
+
+ @Override
+ protected String getServletName() {
+ return "Xmpp dispatcher servlet";
+ }
}
diff --git a/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferConfiguration.java b/juick-xmpp/src/main/java/com/juick/components/configuration/XmppMvcConfiguration.java
index de47ddc9..4a0e8ced 100644
--- a/juick-xmpp-ft/src/main/java/com/juick/components/configuration/FileTransferConfiguration.java
+++ b/juick-xmpp/src/main/java/com/juick/components/configuration/XmppMvcConfiguration.java
@@ -2,57 +2,35 @@ package com.juick.components.configuration;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
-import com.juick.components.XMPPFTServer;
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.apache.commons.dbcp2.BasicDataSource;
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.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.jdbc.core.JdbcTemplate;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
-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", ignoreResourceNotFound = true)
-public class FileTransferConfiguration extends WebMvcConfigurationSupport {
- @Inject
- Environment env;
- @Inject
- ExecutorService service;
+@ComponentScan(basePackages = {"com.juick.components.controllers"})
+@PropertySource("classpath:juick.conf")
+public class XmppMvcConfiguration extends WebMvcConfigurationSupport {
@Bean
- JdbcTemplate jdbc() {
- BasicDataSource dataSource = new BasicDataSource();
- dataSource.setDriverClassName(env.getProperty("datasource_driver", "com.mysql.jdbc.Driver"));
- dataSource.setUrl(env.getProperty("datasource_url"));
- return new JdbcTemplate(dataSource);
- }
- @Inject
- private ServletContext servletContext;
-
- @Bean
- public Loader templateLoader(){
- return new ServletLoader(servletContext);
+ public Loader templateLoader() {
+ return new ServletLoader(getServletContext());
}
@Bean
@@ -76,14 +54,6 @@ public class FileTransferConfiguration extends WebMvcConfigurationSupport {
viewResolver.setPebbleEngine(pebbleEngine());
return viewResolver;
}
- @Bean
- public XMPPFTServer xmpp() {
- return new XMPPFTServer(env);
- }
- @Bean
- public ExecutorService service() {
- return Executors.newCachedThreadPool();
- }
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {