aboutsummaryrefslogtreecommitdiff
path: root/juick-xmpp/src/main/java/com/juick/components/s2s/ConnectionRouter.java
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2016-11-11 11:39:56 +0300
committerGravatar Vitaly Takmazov2016-11-11 11:39:56 +0300
commit3d977963dfe55c0f14720da8c671f77bf210229d (patch)
tree17fc515252b76c43c48f9bf02a2b85af2c626089 /juick-xmpp/src/main/java/com/juick/components/s2s/ConnectionRouter.java
parent2629afbbf5fdd8a23703fafa89bf7a6789de98bb (diff)
xmpp: revert to Connection-based router because Stream-based router can not route full stanzas
Diffstat (limited to 'juick-xmpp/src/main/java/com/juick/components/s2s/ConnectionRouter.java')
-rw-r--r--juick-xmpp/src/main/java/com/juick/components/s2s/ConnectionRouter.java250
1 files changed, 250 insertions, 0 deletions
diff --git a/juick-xmpp/src/main/java/com/juick/components/s2s/ConnectionRouter.java b/juick-xmpp/src/main/java/com/juick/components/s2s/ConnectionRouter.java
new file mode 100644
index 00000000..86f12b82
--- /dev/null
+++ b/juick-xmpp/src/main/java/com/juick/components/s2s/ConnectionRouter.java
@@ -0,0 +1,250 @@
+package com.juick.components.s2s;
+
+import com.juick.User;
+import com.juick.components.XMPPServer;
+import com.juick.server.MessagesQueries;
+import com.juick.server.SubscriptionsQueries;
+import com.juick.server.UserQueries;
+import com.juick.xmpp.JID;
+import com.juick.xmpp.Message;
+import com.juick.xmpp.extensions.JuickMessage;
+import com.juick.xmpp.extensions.Nickname;
+import com.juick.xmpp.extensions.XOOB;
+import com.juick.xmpp.utils.XmlUtils;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.InetSocketAddress;
+import java.nio.channels.AsynchronousSocketChannel;
+import java.nio.channels.Channels;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author ugnich
+ */
+public class ConnectionRouter extends Connection implements Runnable {
+
+ private static final Logger logger = LoggerFactory.getLogger(ConnectionRouter.class);
+
+ private String componentName;
+ private int componentPort;
+ private String password;
+
+ public ConnectionRouter(XMPPServer s2s, String componentName, int componentPort, String password) throws Exception {
+ super(s2s);
+ this.componentName = componentName;
+ this.componentPort = componentPort;
+ this.password = password;
+ }
+
+ @Override
+ public void run() {
+ logger.info("STREAM ROUTER START");
+
+ try {
+ AsynchronousSocketChannel socket = AsynchronousSocketChannel.open();
+ socket.connect(new InetSocketAddress(componentPort));
+ parser.setInput(new InputStreamReader(Channels.newInputStream(socket)));
+ parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
+ writer = new OutputStreamWriter(Channels.newOutputStream(socket));
+
+ String msg = String.format("<stream:stream xmlns='jabber:component:accept' " +
+ "xmlns:stream='http://etherx.jabber.org/streams' to='%s'>", componentName);
+ writer.write(msg);
+ writer.flush();
+
+ parser.next(); // stream:stream
+ streamID = parser.getAttributeValue(null, "id");
+ if (streamID == null || streamID.isEmpty()) {
+ throw new Exception("FAIL ON FIRST PACKET");
+ }
+
+ msg = "<handshake>" + DigestUtils.sha1Hex(streamID + password) + "</handshake>";
+ writer.write(msg);
+ writer.flush();
+
+ parser.next();
+ if (!parser.getName().equals("handshake")) {
+ throw new Exception("NO HANDSHAKE");
+ }
+ XmlUtils.skip(parser);
+ logger.info("STREAM ROUTER OPEN");
+
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ if (parser.getEventType() != XmlPullParser.START_TAG) {
+ continue;
+ }
+
+ String tag = parser.getName();
+ String to = parser.getAttributeValue(null, "to");
+ if (to != null && (tag.equals("message") || tag.equals("presence") || tag.equals("iq"))) {
+ JID jid = new JID(to);
+ if (jid.Host != null) {
+ if (jid.Host.equals(componentName)) {
+ if (tag.equals("message")) {
+ Message xmsg = Message.parse(parser, xmpp.childParsers);
+ logger.info("STREAM ROUTER (PROCESS): " + xmsg.toString());
+ JuickMessage jmsg = (JuickMessage) xmsg.getChild(JuickMessage.XMLNS);
+ if (jmsg != null) {
+ if (jid.Username != null && jid.Username.equals("recomm")) {
+ sendJuickRecommendation(jmsg);
+ } else {
+ if (jmsg.getRID() > 0) {
+ sendJuickComment(jmsg);
+ } else if (jmsg.getMID() > 0) {
+ sendJuickMessage(jmsg);
+ }
+ }
+ }
+ }
+ } else if (jid.Host.endsWith(xmpp.HOSTNAME) && (jid.Host.equals(xmpp.HOSTNAME) || jid.Host.endsWith("." + xmpp.HOSTNAME))) {
+ String xml = XmlUtils.parseToString(parser, true);
+ logger.info("STREAM ROUTER: " + xml);
+ } else {
+ String xml = XmlUtils.parseToString(parser, true);
+ logger.info("STREAM ROUTER (OUT): " + xml);
+ xmpp.sendOut(jid.Host, xml);
+ }
+ } else {
+ logger.info("STREAM ROUTER (NO TO): " + XmlUtils.parseToString(parser, true));
+ }
+ } else {
+ logger.info("STREAM ROUTER: " + XmlUtils.parseToString(parser, true));
+ }
+ }
+
+ logger.warn("STREAM ROUTER FINISHED");
+ } catch (Exception e) {
+ logger.warn("STREAM ROUTER PARSE ERROR: " + e.toString());
+ }
+ }
+
+ public void sendJuickMessage(JuickMessage jmsg) {
+ List<String> jids = new ArrayList<>();
+
+ if (jmsg.FriendsOnly) {
+ jids = SubscriptionsQueries.getJIDSubscribedToUser(xmpp.jdbc, jmsg.getUser().getUID(), jmsg.FriendsOnly);
+ } else {
+ List<User> users = SubscriptionsQueries.getSubscribedUsers(xmpp.jdbc, jmsg.getUser().getUID(), jmsg.getMID());
+ for (User user : users) {
+ for (String jid : UserQueries.getJIDsbyUID(xmpp.jdbc, user.getUID())) {
+ jids.add(jid);
+ }
+ }
+ }
+
+ String txt = "@" + jmsg.getUser().getUName() + ":" + jmsg.getTagsString() + "\n";
+ String attachment = jmsg.getAttachmentURL();
+ if (attachment != null) {
+ txt += attachment + "\n";
+ }
+ txt += jmsg.getText() + "\n\n";
+ txt += "#" + jmsg.getMID() + " http://juick.com/" + jmsg.getMID();
+
+ Nickname nick = new Nickname();
+ nick.Nickname = "@" + jmsg.getUser().getUName();
+
+ com.juick.xmpp.Message msg = new com.juick.xmpp.Message();
+ msg.from = xmpp.bot.getJid();
+ msg.body = txt;
+ msg.type = Message.Type.chat;
+ msg.thread = "juick-" + jmsg.getMID();
+ msg.addChild(jmsg);
+ msg.addChild(nick);
+ if (attachment != null) {
+ XOOB oob = new XOOB();
+ oob.URL = attachment;
+ msg.addChild(oob);
+ }
+
+ for (String jid : jids) {
+ msg.to = new JID(jid);
+ xmpp.sendOut(msg);
+ }
+ }
+
+ public void sendJuickComment(JuickMessage jmsg) {
+ List<User> users;
+ String replyQuote;
+ String replyTo;
+
+ users = SubscriptionsQueries.getUsersSubscribedToComments(xmpp.jdbc, jmsg.getMID(), jmsg.getUser().getUID());
+ com.juick.Message replyMessage = jmsg.ReplyTo > 0 ? MessagesQueries.getReply(xmpp.jdbc, jmsg.getMID(), jmsg.ReplyTo)
+ : MessagesQueries.getMessage(xmpp.jdbc, jmsg.getMID());
+ replyTo = replyMessage.getUser().getUName();
+ replyQuote = replyMessage.getReplyQuote();
+
+ String txt = "Reply by @" + jmsg.getUser().getUName() + ":\n" + replyQuote + "\n@" + replyTo + " ";
+ String attachment = jmsg.getAttachmentURL();
+ if (attachment != null) {
+ txt += attachment + "\n";
+ }
+ txt += jmsg.getText() + "\n\n" + "#" + jmsg.getMID() + "/" + jmsg.getRID() + " http://juick.com/" + jmsg.getMID() + "#" + jmsg.getRID();
+
+ com.juick.xmpp.Message msg = new com.juick.xmpp.Message();
+ msg.from = xmpp.bot.getJid();
+ msg.body = txt;
+ msg.type = Message.Type.chat;
+ msg.addChild(jmsg);
+ for (User user : users) {
+ for (String jid : UserQueries.getJIDsbyUID(xmpp.jdbc, user.getUID())) {
+ msg.to = new JID(jid);
+ xmpp.sendOut(msg);
+ }
+ }
+ }
+
+ public void sendJuickRecommendation(JuickMessage recomm) {
+ List<User> users;
+ JuickMessage jmsg;
+ jmsg = new JuickMessage(MessagesQueries.getMessage(xmpp.jdbc, recomm.getMID()));
+ users = SubscriptionsQueries.getUsersSubscribedToUserRecommendations(xmpp.jdbc,
+ recomm.getUser().getUID(), recomm.getMID(), jmsg.getUser().getUID());
+
+ String txt = "Recommended by @" + recomm.getUser().getUName() + ":\n";
+ txt += "@" + jmsg.getUser().getUName() + ":" + jmsg.getTagsString() + "\n";
+ String attachment = jmsg.getAttachmentURL();
+ if (attachment != null) {
+ txt += attachment + "\n";
+ }
+ txt += jmsg.getText() + "\n\n";
+ txt += "#" + jmsg.getMID();
+ if (jmsg.Replies > 0) {
+ if (jmsg.Replies % 10 == 1 && jmsg.Replies % 100 != 11) {
+ txt += " (" + jmsg.Replies + " reply)";
+ } else {
+ txt += " (" + jmsg.Replies + " replies)";
+ }
+ }
+ txt += " http://juick.com/" + jmsg.getMID();
+
+ Nickname nick = new Nickname();
+ nick.Nickname = "@" + jmsg.getUser().getUName();
+
+ com.juick.xmpp.Message msg = new com.juick.xmpp.Message();
+ msg.from = xmpp.bot.getJid();
+ msg.body = txt;
+ msg.type = Message.Type.chat;
+ msg.thread = "juick-" + jmsg.getMID();
+ msg.addChild(jmsg);
+ msg.addChild(nick);
+ if (attachment != null) {
+ XOOB oob = new XOOB();
+ oob.URL = attachment;
+ msg.addChild(oob);
+ }
+
+ for (User user : users) {
+ for (String jid : UserQueries.getJIDsbyUID(xmpp.jdbc, user.getUID())) {
+ msg.to = new JID(jid);
+ xmpp.sendOut(msg);
+ }
+ }
+ }
+} \ No newline at end of file