From 2be5fc6e0397b53173aa21298142d5fa66877fa5 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Mon, 6 Feb 2017 12:14:29 +0300 Subject: juick-xmpp: ConnectionRouter uses babbler now --- juick-xmpp/build.gradle | 4 +- .../main/java/com/juick/components/XMPPServer.java | 47 +++- .../com/juick/components/s2s/BasicXmppSession.java | 52 ++++ .../com/juick/components/s2s/ConnectionIn.java | 37 ++- .../com/juick/components/s2s/ConnectionRouter.java | 269 +++++++++------------ .../java/com/juick/components/s2s/JuickBot.java | 255 ++++++++++--------- .../com/juick/components/s2s/StanzaListener.java | 5 +- 7 files changed, 383 insertions(+), 286 deletions(-) create mode 100644 juick-xmpp/src/main/java/com/juick/components/s2s/BasicXmppSession.java (limited to 'juick-xmpp') diff --git a/juick-xmpp/build.gradle b/juick-xmpp/build.gradle index 1e078f44..97955c30 100644 --- a/juick-xmpp/build.gradle +++ b/juick-xmpp/build.gradle @@ -5,7 +5,7 @@ apply plugin: 'com.github.ben-manes.versions' dependencies { compile project(':juick-server') - compile 'com.github.juick:com.juick.xmpp:c77bca6a38' + compile 'com.github.juick:com.juick.xmpp:1a259a1ef7' compile "org.slf4j:slf4j-api:${rootProject.slf4jVersion}" compile "org.springframework:spring-webmvc:${rootProject.springFrameworkVersion}" compile "com.fasterxml.jackson.core:jackson-core:${rootProject.jacksonVersion}" @@ -14,7 +14,6 @@ dependencies { compile 'javax.inject:javax.inject:1' compile 'org.apache.httpcomponents:httpclient:4.5.3' compile 'org.apache.commons:commons-dbcp2:2.1.1' - compile 'net.jodah:failsafe:1.0.3' providedRuntime 'mysql:mysql-connector-java:5.1.40' } @@ -28,5 +27,6 @@ gretty { configurations { all*.exclude module: 'commons-logging' + all*.exclude module: 'slf4j-nop' } 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 4a182cc9..72dba642 100644 --- a/juick-xmpp/src/main/java/com/juick/components/XMPPServer.java +++ b/juick-xmpp/src/main/java/com/juick/components/XMPPServer.java @@ -2,9 +2,6 @@ package com.juick.components; import com.juick.components.s2s.*; import com.juick.service.*; -import com.juick.xmpp.Stanza; -import com.juick.xmpp.StanzaChild; -import com.juick.xmpp.extensions.JuickMessage; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; @@ -13,9 +10,17 @@ import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; import org.xmlpull.v1.XmlPullParserException; import rocks.xmpp.addr.Jid; +import rocks.xmpp.core.session.Extension; +import rocks.xmpp.core.session.XmppSessionConfiguration; +import rocks.xmpp.core.stanza.model.Stanza; +import rocks.xmpp.util.XmppUtils; import javax.inject.Inject; +import javax.xml.bind.JAXBException; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; import java.io.IOException; +import java.io.StringWriter; import java.net.ServerSocket; import java.net.Socket; import java.security.KeyManagementException; @@ -46,8 +51,6 @@ public class XMPPServer implements AutoCloseable { private final List outCache = Collections.synchronizedList(new ArrayList<>()); private final List stanzaListeners = Collections.synchronizedList(new ArrayList<>()); - final public HashMap childParsers = new HashMap<>(); - @Inject public MessagesService messagesService; @Inject @@ -63,12 +66,18 @@ public class XMPPServer implements AutoCloseable { private ServerSocket listener; + private BasicXmppSession session; + public XMPPServer(Environment env, ExecutorService service) { this.service = service; + XmppSessionConfiguration configuration = XmppSessionConfiguration.builder() + .extensions(Extension.of(com.juick.Message.class)) + .build(); logger.info("component initialized"); try { HOSTNAME = env.getProperty("hostname"); + session = BasicXmppSession.create(HOSTNAME, configuration); componentName = env.getProperty("componentname"); int componentPort = NumberUtils.toInt(env.getProperty("component_port"), 5347); int s2sPort = NumberUtils.toInt(env.getProperty("s2s_port"), 5269); @@ -79,8 +88,6 @@ public class XMPPServer implements AutoCloseable { jid = Jid.of(env.getProperty("xmppbot_jid")); boolean disabled = BooleanUtils.toBoolean(env.getProperty("xmpp_disabled", "false")); - childParsers.put(JuickMessage.XMLNS, new JuickMessage()); - if (!disabled) { router = new ConnectionRouter(this, componentName, componentPort, env.getProperty("xmpp_password")); service.submit(router); @@ -196,7 +203,19 @@ public class XMPPServer implements AutoCloseable { } public void sendOut(Stanza s) { - sendOut(s.to.getDomain(), s.toString()); + try { + StringWriter stanzaWriter = new StringWriter(); + XMLStreamWriter xmppStreamWriter = XmppUtils.createXmppStreamWriter( + session.getConfiguration().getXmlOutputFactory().createXMLStreamWriter(stanzaWriter)); + session.createMarshaller().marshal(s, xmppStreamWriter); + xmppStreamWriter.flush(); + xmppStreamWriter.close(); + String xml = stanzaWriter.toString(); + logger.info("s2s (out): {}", xml); + sendOut(s.getTo().getDomain(), xml); + } catch (XMLStreamException | JAXBException e1) { + logger.info("jaxb exception", e1); + } } public void sendOut(String hostname, String xml) { @@ -282,11 +301,19 @@ public class XMPPServer implements AutoCloseable { } } - public void onStanzaReceived(String type, Stanza xmlValue) { - stanzaListeners.forEach(l -> l.stanzaReceived(type, xmlValue)); + public void onStanzaReceived(Stanza xmlValue) { + stanzaListeners.forEach(l -> l.stanzaReceived(xmlValue)); } public Jid getJid() { return jid; } + + public BasicXmppSession getSession() { + return session; + } + + public void setSession(BasicXmppSession session) { + this.session = session; + } } diff --git a/juick-xmpp/src/main/java/com/juick/components/s2s/BasicXmppSession.java b/juick-xmpp/src/main/java/com/juick/components/s2s/BasicXmppSession.java new file mode 100644 index 00000000..8a6a65ee --- /dev/null +++ b/juick-xmpp/src/main/java/com/juick/components/s2s/BasicXmppSession.java @@ -0,0 +1,52 @@ +package com.juick.components.s2s; + +import rocks.xmpp.addr.Jid; +import rocks.xmpp.core.XmppException; +import rocks.xmpp.core.session.ConnectionConfiguration; +import rocks.xmpp.core.session.XmppSession; +import rocks.xmpp.core.session.XmppSessionConfiguration; +import rocks.xmpp.core.stanza.model.IQ; +import rocks.xmpp.core.stanza.model.Message; +import rocks.xmpp.core.stanza.model.Presence; +import rocks.xmpp.core.stanza.model.server.ServerIQ; +import rocks.xmpp.core.stanza.model.server.ServerMessage; +import rocks.xmpp.core.stanza.model.server.ServerPresence; +import rocks.xmpp.core.stream.model.StreamElement; + +/** + * Created by vitalyster on 06.02.2017. + */ +public class BasicXmppSession extends XmppSession { + protected BasicXmppSession(String xmppServiceDomain, XmppSessionConfiguration configuration, ConnectionConfiguration... connectionConfigurations) { + super(xmppServiceDomain, configuration, connectionConfigurations); + } + + public static BasicXmppSession create(String xmppServiceDomain, XmppSessionConfiguration configuration) { + BasicXmppSession session = new BasicXmppSession(xmppServiceDomain, configuration); + notifyCreationListeners(session); + return session; + } + + @Override + public void connect(Jid from) throws XmppException { + + } + + @Override + public Jid getConnectedResource() { + return null; + } + + @Override + protected StreamElement prepareElement(StreamElement element) { + if (element instanceof Message) { + element = ServerMessage.from((Message) element); + } else if (element instanceof Presence) { + element = ServerPresence.from((Presence) element); + } else if (element instanceof IQ) { + element = ServerIQ.from((IQ) element); + } + + return element; + } +} diff --git a/juick-xmpp/src/main/java/com/juick/components/s2s/ConnectionIn.java b/juick-xmpp/src/main/java/com/juick/components/s2s/ConnectionIn.java index 1cd914c9..7bb02fa5 100644 --- a/juick-xmpp/src/main/java/com/juick/components/s2s/ConnectionIn.java +++ b/juick-xmpp/src/main/java/com/juick/components/s2s/ConnectionIn.java @@ -2,17 +2,20 @@ package com.juick.components.s2s; import com.juick.components.XMPPServer; import com.juick.xmpp.Iq; -import com.juick.xmpp.Message; -import com.juick.xmpp.Presence; import com.juick.xmpp.extensions.StreamError; import com.juick.xmpp.utils.XmlUtils; import org.xmlpull.v1.XmlPullParser; import rocks.xmpp.addr.Jid; +import rocks.xmpp.core.session.XmppSessionConfiguration; +import rocks.xmpp.core.stanza.model.Stanza; import javax.net.ssl.SSLException; import javax.net.ssl.SSLSocket; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; import java.io.EOFException; import java.io.IOException; +import java.io.StringReader; import java.net.Socket; import java.net.SocketException; import java.util.ArrayList; @@ -27,6 +30,7 @@ public class ConnectionIn extends Connection implements Runnable { final public List from = new ArrayList<>(); public long tsRemoteData = 0; public long packetsRemote = 0; + XmppSessionConfiguration configuration; public ConnectionIn(XMPPServer xmpp, Socket socket) throws Exception { super(xmpp); @@ -34,6 +38,16 @@ public class ConnectionIn extends Connection implements Runnable { restartParser(); } + protected Stanza parse(String xml) { + try { + Unmarshaller unmarshaller = xmpp.getSession().createUnmarshaller(); + return (Stanza)unmarshaller.unmarshal(new StringReader(xml)); + } catch (JAXBException e) { + logger.error("JAXB exception", e); + } + return null; + } + @Override public void run() { try { @@ -103,23 +117,22 @@ public class ConnectionIn extends Connection implements Runnable { logger.warn("stream from {} {} dialback verify invalid", vfrom, streamID); } } else if (tag.equals("presence") && checkFromTo(parser)) { - Presence p = Presence.parse(parser, null); - logger.info("stream {}: {}", streamID, p); - xmpp.onStanzaReceived("presence", p); + String xml = XmlUtils.parseToString(parser, false); + logger.info("stream {} presence: {}", streamID, xml); + xmpp.onStanzaReceived(parse(xml)); } else if (tag.equals("message") && checkFromTo(parser)) { updateTsRemoteData(); - Message msg = Message.parse(parser, xmpp.childParsers); - if (msg != null && (msg.type == null || !msg.type.equals(Message.Type.error))) { - logger.info("stream {}: {}", streamID, msg); - xmpp.onStanzaReceived("message", msg); - } + String xml = XmlUtils.parseToString(parser, false); + logger.info("stream {} message: {}", streamID, xml); + xmpp.onStanzaReceived(parse(xml)); + } else if (tag.equals("iq") && checkFromTo(parser)) { updateTsRemoteData(); String type = parser.getAttributeValue(null, "type"); - String xml = XmlUtils.parseToString(parser, true); + String xml = XmlUtils.parseToString(parser, false); if (type == null || !type.equals(Iq.Type.error)) { logger.info("stream {}: {}", streamID, xml); - xmpp.getRouter().sendStanza(xml); + xmpp.getRouter().sendStanza(parse(xml)); } } else if (sc != null && !isSecured() && tag.equals("starttls")) { logger.info("stream {} securing", streamID); 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 index f0fc3c60..16c2019a 100644 --- a/juick-xmpp/src/main/java/com/juick/components/s2s/ConnectionRouter.java +++ b/juick-xmpp/src/main/java/com/juick/components/s2s/ConnectionRouter.java @@ -2,44 +2,43 @@ package com.juick.components.s2s; import com.juick.User; import com.juick.components.XMPPServer; -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 net.jodah.failsafe.Execution; -import net.jodah.failsafe.RetryPolicy; -import org.apache.commons.codec.digest.DigestUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; import rocks.xmpp.addr.Jid; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.net.InetSocketAddress; -import java.nio.channels.AsynchronousSocketChannel; -import java.nio.channels.Channels; +import rocks.xmpp.core.XmppException; +import rocks.xmpp.core.session.Extension; +import rocks.xmpp.core.session.XmppSessionConfiguration; +import rocks.xmpp.core.stanza.model.Message; +import rocks.xmpp.core.stanza.model.Stanza; +import rocks.xmpp.extensions.component.accept.ExternalComponent; +import rocks.xmpp.extensions.nick.model.Nickname; +import rocks.xmpp.extensions.oob.model.x.OobX; +import rocks.xmpp.util.XmppUtils; + +import javax.xml.bind.JAXBException; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; +import java.io.StringWriter; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.TimeUnit; /** * @author ugnich */ -public class ConnectionRouter extends Connection implements Runnable, AutoCloseable { +public class ConnectionRouter implements Runnable, AutoCloseable { private static final Logger logger = LoggerFactory.getLogger(ConnectionRouter.class); private String componentName; private int componentPort; private String password; - private Execution execution; + private ExternalComponent router; + private XMPPServer xmpp; public ConnectionRouter(XMPPServer s2s, String componentName, int componentPort, String password) throws Exception { - super(s2s); + this.xmpp = s2s; this.componentName = componentName; this.componentPort = componentPort; this.password = password; @@ -48,104 +47,65 @@ public class ConnectionRouter extends Connection implements Runnable, AutoClosea @Override public void run() { logger.info("stream router start"); - @SuppressWarnings("unchecked") RetryPolicy retryPolicy = new RetryPolicy() - .withBackoff(1, 30, TimeUnit.SECONDS) - .withJitter(0.1) - .retryOn(IOException.class, XmlPullParserException.class); - execution = new Execution(retryPolicy); - xmpp.service.submit(() -> { - while (!execution.isComplete()) { - try { - AsynchronousSocketChannel socket = AsynchronousSocketChannel.open(); - socket.connect(new InetSocketAddress("localhost", componentPort)).get(); - parser.setInput(new InputStreamReader(Channels.newInputStream(socket))); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - writer = new OutputStreamWriter(Channels.newOutputStream(socket)); - - String msg = String.format("", 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 = "" + DigestUtils.sha1Hex(streamID + password) + ""; - 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 = Jid.of(to); - if (jid.getDomain() != null) { - if (jid.getDomain().equals(componentName)) { - if (tag.equals("message")) { - Message xmsg = Message.parse(parser, xmpp.childParsers); - logger.info("stream router (process): {}", xmsg); - JuickMessage jmsg = (JuickMessage) xmsg.getChild(JuickMessage.XMLNS); - if (jmsg != null) { - if (jid.getLocal() != null && jid.getLocal().equals("recomm")) { - sendJuickRecommendation(jmsg); - } else { - if (jmsg.getRid() > 0) { - sendJuickComment(jmsg); - } else if (jmsg.getMid() > 0) { - sendJuickMessage(jmsg); - } - } - } - } else if (tag.equals("iq") || tag.equals("presence")) { - String xml = XmlUtils.parseToString(parser, true); - logger.info("stream router (stanza): {}", xml); - } - } else if (jid.getDomain().endsWith(xmpp.HOSTNAME) && (jid.getDomain().equals(xmpp.HOSTNAME) - || jid.getDomain().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.getDomain(), xml); - } - } else { - String invalidStanza = XmlUtils.parseToString(parser, true); - logger.info("stream router (no to): {}", invalidStanza); - } - } else { - String unknownStanza = XmlUtils.parseToString(parser, true); - logger.info("stream router (unknown): {}", unknownStanza); + XmppSessionConfiguration configuration = XmppSessionConfiguration.builder() + .extensions(Extension.of(com.juick.Message.class)) + .build(); + router = ExternalComponent.create(componentName, password, configuration, "localhost", componentPort); + router.addInboundMessageListener(e -> { + Message message = e.getMessage(); + Jid jid = message.getTo(); + if (jid.getDomain().equals(Jid.of(componentName).getDomain())) { + com.juick.Message jmsg = message.getExtension(com.juick.Message.class); + if (jmsg != null) { + if (jid.getLocal().equals("recomm")) { + sendJuickRecommendation(jmsg); + } else { + if (jmsg.getRid() > 0) { + sendJuickComment(jmsg); + } else if (jmsg.getMid() > 0) { + sendJuickMessage(jmsg); } } - - logger.warn("stream router finished"); - } catch (InterruptedException ex) { - logger.info("shutting down"); - execution.complete(); - } catch (Exception e) { - logger.warn("router error, reconnection ", e); - execution.recordFailure(e); } + } else if (jid.getDomain().endsWith(xmpp.HOSTNAME) && (jid.getDomain().equals(xmpp.HOSTNAME) + || jid.getDomain().endsWith("." + xmpp.HOSTNAME))) { + logger.info("skip"); + } else { + route(jid.getDomain(), message); + } + }); + xmpp.service.submit(() -> { + try { + router.connect(); + } catch (XmppException e) { + logger.warn("xmpp exception", e); } }); } - public void sendJuickMessage(JuickMessage jmsg) { + void route(String domain, Stanza stanza) { + try { + StringWriter stanzaWriter = new StringWriter(); + XMLStreamWriter xmppStreamWriter = XmppUtils.createXmppStreamWriter( + router.getConfiguration().getXmlOutputFactory().createXMLStreamWriter(stanzaWriter)); + router.createMarshaller().marshal(stanza, xmppStreamWriter); + xmppStreamWriter.flush(); + xmppStreamWriter.close(); + String xml = stanzaWriter.toString(); + logger.info("stream router (out): {}", xml); + xmpp.sendOut(domain, xml); + } catch (XMLStreamException | JAXBException e1) { + logger.info("jaxb exception", e1); + } + } + + void sendStanza(Stanza xml) { + router.send(xml); + } + + + + public void sendJuickMessage(com.juick.Message jmsg) { List jids = new ArrayList<>(); if (jmsg.FriendsOnly) { @@ -167,29 +127,31 @@ public class ConnectionRouter extends Connection implements Runnable, AutoClosea txt += jmsg.getText() + "\n\n"; txt += "#" + jmsg.getMid() + " http://juick.com/" + jmsg.getMid(); - Nickname nick = new Nickname(); - nick.Nickname = "@" + jmsg.getUser().getName(); + Nickname nick = new Nickname("@" + jmsg.getUser().getName()); - com.juick.xmpp.Message msg = new com.juick.xmpp.Message(); - msg.from = xmpp.getJid(); - msg.body = txt; - msg.type = Message.Type.chat; - msg.thread = "juick-" + jmsg.getMid(); - msg.addChild(jmsg); - msg.addChild(nick); + Message msg = new Message(); + msg.setFrom(xmpp.getJid()); + msg.setBody(txt); + msg.setType(Message.Type.CHAT); + msg.setThread("juick-" + jmsg.getMid()); + msg.addExtension(jmsg); + msg.addExtension(nick); if (attachment != null) { - XOOB oob = new XOOB(); - oob.URL = attachment; - msg.addChild(oob); + try { + OobX oob = new OobX(new URI(attachment)); + msg.addExtension(oob); + } catch (URISyntaxException e) { + logger.warn("uri exception", e); + } } for (String jid : jids) { - msg.to = Jid.of(jid); - xmpp.sendOut(msg); + msg.setTo(Jid.of(jid)); + route(msg.getTo().getDomain(), msg); } } - public void sendJuickComment(JuickMessage jmsg) { + public void sendJuickComment(com.juick.Message jmsg) { List users; String replyQuote; String replyTo; @@ -208,23 +170,22 @@ public class ConnectionRouter extends Connection implements Runnable, AutoClosea } 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.getJid(); - msg.body = txt; - msg.type = Message.Type.chat; - msg.addChild(jmsg); + Message msg = new Message(); + msg.setFrom(xmpp.getJid()); + msg.setBody(txt); + msg.setType(Message.Type.CHAT); + msg.addExtension(jmsg); for (User user : users) { for (String jid : xmpp.userService.getJIDsbyUID(user.getUid())) { - msg.to = Jid.of(jid); - xmpp.sendOut(msg); + msg.setTo(Jid.of(jid)); + route(msg.getTo().getDomain(), msg); } } } - public void sendJuickRecommendation(JuickMessage recomm) { + public void sendJuickRecommendation(com.juick.Message recomm) { List users; - JuickMessage jmsg; - jmsg = new JuickMessage(xmpp.messagesService.getMessage(recomm.getMid())); + com.juick.Message jmsg = xmpp.messagesService.getMessage(recomm.getMid()); users = xmpp.subscriptionService.getUsersSubscribedToUserRecommendations(recomm.getUser().getUid(), recomm.getMid(), jmsg.getUser().getUid()); @@ -245,32 +206,36 @@ public class ConnectionRouter extends Connection implements Runnable, AutoClosea } txt += " http://juick.com/" + jmsg.getMid(); - Nickname nick = new Nickname(); - nick.Nickname = "@" + jmsg.getUser().getName(); + Nickname nick = new Nickname("@" + jmsg.getUser().getName()); - com.juick.xmpp.Message msg = new com.juick.xmpp.Message(); - msg.from = xmpp.getJid(); - msg.body = txt; - msg.type = Message.Type.chat; - msg.thread = "juick-" + jmsg.getMid(); - msg.addChild(jmsg); - msg.addChild(nick); + Message msg = new Message(); + msg.setFrom(xmpp.getJid()); + msg.setBody(txt); + msg.setType(Message.Type.CHAT); + msg.setThread("juick-" + jmsg.getMid()); + msg.addExtension(jmsg); + msg.addExtension(nick); if (attachment != null) { - XOOB oob = new XOOB(); - oob.URL = attachment; - msg.addChild(oob); + try { + OobX oob = new OobX(new URI(attachment)); + msg.addExtension(oob); + } catch (URISyntaxException e) { + logger.warn("uri exception", e); + } } for (User user : users) { for (String jid : xmpp.userService.getJIDsbyUID(user.getUid())) { - msg.to = Jid.of(jid); - xmpp.sendOut(msg); + msg.setTo(Jid.of(jid)); + route(msg.getTo().getDomain(), msg); } } } @Override public void close() throws Exception { - execution.complete(); + if (router != null) { + router.close(); + } } } diff --git a/juick-xmpp/src/main/java/com/juick/components/s2s/JuickBot.java b/juick-xmpp/src/main/java/com/juick/components/s2s/JuickBot.java index f309bd21..cf791ada 100644 --- a/juick-xmpp/src/main/java/com/juick/components/s2s/JuickBot.java +++ b/juick-xmpp/src/main/java/com/juick/components/s2s/JuickBot.java @@ -2,13 +2,15 @@ package com.juick.components.s2s; import com.juick.User; import com.juick.components.XMPPServer; -import com.juick.xmpp.Message; -import com.juick.xmpp.Presence; -import com.juick.xmpp.Stanza; -import com.juick.xmpp.extensions.XMPPError; -import com.juick.xmpp.extensions.JuickMessage; import org.apache.commons.lang3.StringUtils; import rocks.xmpp.addr.Jid; +import rocks.xmpp.core.stanza.model.Message; +import rocks.xmpp.core.stanza.model.Presence; +import rocks.xmpp.core.stanza.model.Stanza; +import rocks.xmpp.core.stanza.model.StanzaError; +import rocks.xmpp.core.stanza.model.client.ClientMessage; +import rocks.xmpp.core.stanza.model.client.ClientPresence; +import rocks.xmpp.core.stanza.model.errors.Condition; import javax.inject.Inject; import java.util.List; @@ -64,17 +66,17 @@ public class JuickBot implements StanzaListener { + "Read more: http://juick.com/help/"; public boolean incomingPresence(Presence p) { - final String username = p.to.getLocal(); + final String username = p.getTo().getLocal(); final boolean toJuick = username.equals("juick"); - if (p.type == null) { + if (p.getType() == null) { Presence reply = new Presence(); - reply.from = p.to.asBareJid(); - reply.to = p.from.asBareJid(); - reply.type = Presence.Type.unsubscribe; - xmpp.sendOut(reply); + reply.setFrom(p.getTo().asBareJid()); + reply.setTo(p.getFrom().asBareJid()); + reply.setType(Presence.Type.UNSUBSCRIBE); + xmpp.sendOut(ClientPresence.from(reply)); return true; - } else if (p.type.equals(Presence.Type.probe)) { + } else if (p.getType().equals(Presence.Type.PROBE)) { int uid_to = 0; if (!toJuick) { uid_to = xmpp.userService.getUIDbyName(username); @@ -82,84 +84,100 @@ public class JuickBot implements StanzaListener { if (toJuick || uid_to > 0) { Presence reply = new Presence(); - reply.from = p.to.withResource("Juick"); - reply.to = p.from; - reply.priority = 10; - xmpp.sendOut(reply); + reply.setFrom(p.getTo().withResource("Juick")); + reply.setTo(p.getFrom()); + reply.setPriority((byte)10); + xmpp.sendOut(ClientPresence.from(reply)); } else { - Presence reply = new Presence(p.to, p.from, Presence.Type.error); - reply.id = p.id; - reply.addChild(new XMPPError(XMPPError.Type.cancel, "item-not-found")); - xmpp.sendOut(reply); + Presence reply = new Presence(); + reply.setFrom(p.getTo()); + reply.setTo(p.getFrom()); + reply.setType(Presence.Type.ERROR); + reply.setId(p.getId()); + StanzaError stanzaError = new StanzaError(StanzaError.Type.CANCEL, Condition.ITEM_NOT_FOUND); + reply.addExtension(stanzaError); + xmpp.sendOut(ClientPresence.from(reply)); return true; } return true; - } else if (p.type.equals(Presence.Type.subscribe)) { + } else if (p.getType().equals(Presence.Type.SUBSCRIBE)) { boolean canSubscribe = false; if (toJuick) { canSubscribe = true; } else { int uid_to = xmpp.userService.getUIDbyName(username); if (uid_to > 0) { - xmpp.pmQueriesService.addPMinRoster(uid_to, p.from.asBareJid().toEscapedString()); + xmpp.pmQueriesService.addPMinRoster(uid_to, p.getFrom().asBareJid().toEscapedString()); canSubscribe = true; } } if (canSubscribe) { - Presence reply = new Presence(p.to, p.from, Presence.Type.subscribed); - xmpp.sendOut(reply); + Presence reply = new Presence(); + reply.setFrom(p.getTo()); + reply.setTo(p.getFrom()); + reply.setType(Presence.Type.SUBSCRIBED); + xmpp.sendOut(ClientPresence.from(reply)); - reply.from = reply.from.withResource("Juick"); - reply.priority = 10; - reply.type = null; - xmpp.sendOut(reply); + reply.setFrom(reply.getFrom().withResource("Juick")); + reply.setPriority((byte) 10); + reply.setType(null); + xmpp.sendOut(ClientPresence.from(reply)); return true; } else { - Presence reply = new Presence(p.to, p.from, Presence.Type.error); - reply.id = p.id; - reply.addChild(new XMPPError(XMPPError.Type.cancel, "item-not-found")); - xmpp.sendOut(reply); + Presence reply = new Presence(); + reply.setFrom(p.getTo()); + reply.setTo(p.getFrom()); + reply.setType(Presence.Type.ERROR); + reply.setId(p.getId()); + reply.addExtension(new StanzaError(StanzaError.Type.CANCEL, Condition.ITEM_NOT_FOUND)); + xmpp.sendOut(ClientPresence.from(reply)); return true; } - } else if (p.type.equals(Presence.Type.unsubscribe)) { + } else if (p.getType().equals(Presence.Type.UNSUBSCRIBE)) { if (!toJuick) { int uid_to = xmpp.userService.getUIDbyName(username); if (uid_to > 0) { - xmpp.pmQueriesService.removePMinRoster(uid_to, p.from.asBareJid().toEscapedString()); + xmpp.pmQueriesService.removePMinRoster(uid_to, p.getFrom().asBareJid().toEscapedString()); } } - Presence reply = new Presence(p.to, p.from, Presence.Type.unsubscribed); - xmpp.sendOut(reply); + Presence reply = new Presence(); + reply.setFrom(p.getTo()); + reply.setTo(p.getFrom()); + reply.setType(Presence.Type.UNSUBSCRIBED); + xmpp.sendOut(ClientPresence.from(reply)); } return false; } public boolean incomingMessage(Message msg) { - if (msg.body == null || msg.body.isEmpty()) { + if (StringUtils.isBlank(msg.getBody())) { return false; } - String username = msg.to.getLocal(); + String username = msg.getTo().getLocal(); User user_from; String signuphash = StringUtils.EMPTY; - user_from = xmpp.userService.getUserByJID(msg.from.asBareJid().toEscapedString()); + user_from = xmpp.userService.getUserByJID(msg.getFrom().asBareJid().toEscapedString()); if (user_from == null) { - signuphash = xmpp.userService.getSignUpHashByJID(msg.from.asBareJid().toEscapedString()); + signuphash = xmpp.userService.getSignUpHashByJID(msg.getFrom().asBareJid().toEscapedString()); } if (user_from == null) { - Message reply = new Message(msg.to, msg.from, Message.Type.chat); + Message reply = new Message(); + reply.setFrom(msg.getTo()); + reply.setTo(msg.getFrom()); + reply.setType(Message.Type.CHAT); if (username.equals("juick")) { - reply.body = "Для того, чтобы начать пользоваться сервисом, пожалуйста пройдите быструю регистрацию: http://juick.com/signup?type=xmpp&hash=" + signuphash + "\nЕсли у вас уже есть учетная запись на Juick, вы сможете присоединить этот JabberID к ней.\n\nTo start using Juick, please sign up: http://juick.com/signup?type=xmpp&hash=" + signuphash + "\nIf you already have an account on Juick, you will be proposed to attach this JabberID to your existing account."; + reply.setBody("Для того, чтобы начать пользоваться сервисом, пожалуйста пройдите быструю регистрацию: http://juick.com/signup?type=xmpp&hash=" + signuphash + "\nЕсли у вас уже есть учетная запись на Juick, вы сможете присоединить этот JabberID к ней.\n\nTo start using Juick, please sign up: http://juick.com/signup?type=xmpp&hash=" + signuphash + "\nIf you already have an account on Juick, you will be proposed to attach this JabberID to your existing account."); } else { - reply.body = "Внимание, системное сообщение!\nВаш JabberID не обнаружен в списке доверенных. Для того, чтобы отправить сообщение пользователю " + username + "@juick.com, пожалуйста зарегистрируйте свой JabberID в системе: http://juick.com/signup?type=xmpp&hash=" + signuphash + "\nЕсли у вас уже есть учетная запись на Juick, вы сможете присоединить этот JabberID к ней.\n\nWarning, system message!\nYour JabberID is not found in our server's white list. To send a message to " + username + "@juick.com, please sign up: http://juick.com/signup?type=xmpp&hash=" + signuphash + "\nIf you already have an account on Juick, you will be proposed to attach this JabberID to your existing account."; + reply.setBody("Внимание, системное сообщение!\nВаш JabberID не обнаружен в списке доверенных. Для того, чтобы отправить сообщение пользователю " + username + "@juick.com, пожалуйста зарегистрируйте свой JabberID в системе: http://juick.com/signup?type=xmpp&hash=" + signuphash + "\nЕсли у вас уже есть учетная запись на Juick, вы сможете присоединить этот JabberID к ней.\n\nWarning, system message!\nYour JabberID is not found in our server's white list. To send a message to " + username + "@juick.com, please sign up: http://juick.com/signup?type=xmpp&hash=" + signuphash + "\nIf you already have an account on Juick, you will be proposed to attach this JabberID to your existing account."); } - xmpp.sendOut(reply); + xmpp.sendOut(ClientMessage.from(reply)); return true; } @@ -170,53 +188,59 @@ public class JuickBot implements StanzaListener { int uid_to = xmpp.userService.getUIDbyName(username); if (uid_to == 0) { - Message reply = new Message(msg.to, msg.from, Message.Type.error); - reply.id = msg.id; - reply.addChild(new XMPPError(XMPPError.Type.cancel, "item-not-found")); - xmpp.sendOut(reply); + Message reply = new Message(); + reply.setFrom(msg.getTo()); + reply.setTo(msg.getFrom()); + reply.setType(Message.Type.ERROR); + reply.setId(msg.getId()); + reply.addExtension(new StanzaError(StanzaError.Type.CANCEL, Condition.ITEM_NOT_FOUND)); + xmpp.sendOut(ClientMessage.from(reply)); return true; } boolean success = false; if (!xmpp.userService.isInBLAny(uid_to, user_from.getUid())) { - success = xmpp.pmQueriesService.createPM(user_from.getUid(), uid_to, msg.body); + success = xmpp.pmQueriesService.createPM(user_from.getUid(), uid_to, msg.getBody()); } if (success) { Message m = new Message(); - m.from = Jid.of("juick@juick.com"); - m.to = Jid.of(Integer.toString(uid_to), "push.juick.com", null); - JuickMessage jmsg = new JuickMessage(); + m.setFrom(Jid.of("juick@juick.com")); + m.setTo(Jid.of(Integer.toString(uid_to), "push.juick.com", null)); + com.juick.Message jmsg = new com.juick.Message(); jmsg.setUser(user_from); - jmsg.setText(msg.body); - m.childs.add(jmsg); - xmpp.getRouter().sendStanza(m.toString()); + jmsg.setText(msg.getBody()); + m.addExtension(jmsg); + xmpp.getRouter().sendStanza(m); - m.to = Jid.of(Integer.toString(uid_to), "ws.juick.com", null); - xmpp.getRouter().sendStanza(m.toString()); + m.setTo(Jid.of(Integer.toString(uid_to), "ws.juick.com", null)); + xmpp.getRouter().sendStanza(m); List jids; boolean inroster = false; jids = xmpp.userService.getJIDsbyUID(uid_to); for (String jid : jids) { Message mm = new Message(); - mm.to = Jid.of(jid); - mm.type = Message.Type.chat; + mm.setTo(Jid.of(jid)); + mm.setType(Message.Type.CHAT); inroster = xmpp.pmQueriesService.havePMinRoster(user_from.getUid(), jid); if (inroster) { - mm.from = Jid.of(jmsg.getUser().getName(), "juick.com", "Juick"); - mm.body = msg.body; + mm.setFrom(Jid.of(jmsg.getUser().getName(), "juick.com", "Juick")); + mm.setBody(msg.getBody()); } else { - mm.from = Jid.of("juick", "juick.com", "Juick"); - mm.body = "Private message from @" + jmsg.getUser().getName() + ":\n" + msg.body; + mm.setFrom(Jid.of("juick", "juick.com", "Juick")); + mm.setBody("Private message from @" + jmsg.getUser().getName() + ":\n" + msg.getBody()); } - xmpp.sendOut(mm); + xmpp.sendOut(ClientMessage.from(mm)); } } else { - Message reply = new Message(msg.to, msg.from, Message.Type.error); - reply.id = msg.id; - reply.addChild(new XMPPError(XMPPError.Type.cancel, "not-allowed")); - xmpp.sendOut(reply); + Message reply = new Message(); + reply.setFrom(msg.getTo()); + reply.setTo(msg.getFrom()); + reply.setType(Message.Type.ERROR); + reply.setId(msg.getId()); + reply.addExtension(new StanzaError(StanzaError.Type.CANCEL, Condition.NOT_ALLOWED)); + xmpp.sendOut(ClientMessage.from(reply)); } return false; @@ -224,7 +248,7 @@ public class JuickBot implements StanzaListener { private static Pattern regexPM = Pattern.compile("^\\@(\\S+)\\s+([\\s\\S]+)$"); public boolean incomingMessageJuick(User user_from, Message msg) { - String command = msg.body.trim(); + String command = msg.getBody().trim(); int commandlen = command.length(); // COMPATIBILITY @@ -261,25 +285,35 @@ public class JuickBot implements StanzaListener { } private void commandPing(Message m) { - Presence p = new Presence(xmpp.getJid(), m.from); - p.priority = 10; - xmpp.sendOut(p); - - Message reply = new Message(xmpp.getJid(), m.from, Message.Type.chat); - reply.body = "PONG"; - xmpp.sendOut(reply); + Presence p = new Presence(m.getFrom()); + p.setFrom(xmpp.getJid()); + p.setPriority((byte) 10); + xmpp.sendOut(ClientPresence.from(p)); + + Message reply = new Message(); + reply.setFrom(xmpp.getJid()); + reply.setTo(m.getFrom()); + reply.setType(Message.Type.CHAT); + reply.setBody("PONG"); + xmpp.sendOut(ClientMessage.from(reply)); } private void commandHelp(Message m) { - Message reply = new Message(xmpp.getJid(), m.from, Message.Type.chat); - reply.body = HELPTEXT; - xmpp.sendOut(reply); + Message reply = new Message(); + reply.setFrom(xmpp.getJid()); + reply.setTo(m.getFrom()); + reply.setType(Message.Type.CHAT); + reply.setBody(HELPTEXT); + xmpp.sendOut(ClientMessage.from(reply)); } private void commandLogin(Message m, User user_from) { - Message reply = new Message(xmpp.getJid(), m.from, Message.Type.chat); - reply.body = "http://juick.com/login?" + xmpp.userService.getHashByUID(user_from.getUid()); - xmpp.sendOut(reply); + Message reply = new Message(); + reply.setFrom(xmpp.getJid()); + reply.setTo(m.getFrom()); + reply.setType(Message.Type.CHAT); + reply.setBody("http://juick.com/login?" + xmpp.userService.getHashByUID(user_from.getUid())); + xmpp.sendOut(ClientMessage.from(reply)); } private void commandPM(Message m, User user_from, String user_to, String body) { @@ -312,42 +346,44 @@ public class JuickBot implements StanzaListener { if (ret == 200) { Message msg = new Message(); - msg.from = Jid.of("juick", "juick.com", null); - msg.to = Jid.of(Integer.toString(uid_to), "push.juick.com", null); - JuickMessage jmsg = new JuickMessage(); + msg.setFrom(Jid.of("juick", "juick.com", null)); + msg.setTo(Jid.of(Integer.toString(uid_to), "push.juick.com", null)); + com.juick.Message jmsg = new com.juick.Message(); jmsg.setUser(user_from); jmsg.setText(body); - msg.childs.add(jmsg); - xmpp.getRouter().sendStanza(msg.toString()); + msg.addExtension(jmsg); + xmpp.getRouter().sendStanza(msg); - msg.to = Jid.of(Integer.toString(uid_to), "ws.juick.com", null); - xmpp.getRouter().sendStanza(msg.toString()); + msg.setTo(Jid.of(Integer.toString(uid_to), "ws.juick.com", null)); + xmpp.getRouter().sendStanza(msg); for (String jid : jids_to) { Message mm = new Message(); - mm.to = Jid.of(jid); - mm.type = Message.Type.chat; + mm.setTo(Jid.of(jid)); + mm.setType(Message.Type.CHAT); haveInRoster = xmpp.pmQueriesService.havePMinRoster(user_from.getUid(), jid); if (haveInRoster) { - mm.from = Jid.of(user_from.getName(), "juick.com", "Juick"); - mm.body = body; + mm.setFrom(Jid.of(user_from.getName(), "juick.com", "Juick")); + mm.setBody(body); } else { - mm.from = Jid.of("juick", "juick.com", "Juick"); - mm.body = "Private message from @" + user_from.getName() + ":\n" + body; + mm.setFrom(Jid.of("juick", "juick.com", "Juick")); + mm.setBody("Private message from @" + user_from.getName() + ":\n" + body); } - xmpp.sendOut(mm); + xmpp.sendOut(ClientMessage.from(mm)); } } - Message reply = new Message(m.to, m.from); + Message reply = new Message(); + reply.setFrom(m.getTo()); + reply.setTo(m.getFrom()); if (ret == 200) { - reply.type = m.type; - reply.body = "Private message sent"; + reply.setType(m.getType()); + reply.setBody("Private message sent"); } else { - reply.type = Message.Type.error; - reply.body = "Error " + ret; + reply.setType(Message.Type.ERROR); + reply.setBody("Error " + ret); } - xmpp.sendOut(reply); + xmpp.sendOut(ClientMessage.from(reply)); } private void commandBLShow(Message m, User user_from) { @@ -373,22 +409,25 @@ public class JuickBot implements StanzaListener { txt = "You don't have any users or tags in your blacklist."; } - Message reply = new Message(xmpp.getJid(), m.from, Message.Type.chat); - reply.body = txt; - xmpp.sendOut(reply); + Message reply = new Message(); + reply.setFrom(xmpp.getJid()); + reply.setTo(m.getFrom()); + reply.setType(Message.Type.CHAT); + reply.setBody(txt); + xmpp.sendOut(ClientMessage.from(reply)); } @Override - public void stanzaReceived(String name, Stanza xmlValue) { + public void stanzaReceived(Stanza xmlValue) { if (xmlValue instanceof Presence) { Presence p = (Presence) xmlValue; - if (p.type == null || !p.type.equals(Presence.Type.error)) { + if (p.getType() == null || !p.getType().equals(Presence.Type.ERROR)) { incomingPresence(p); } } else if (xmlValue instanceof Message) { Message msg = (Message) xmlValue; if (!incomingMessage(msg)) { - xmpp.getRouter().sendStanza(msg.toString()); + xmpp.getRouter().sendStanza(msg); } } } diff --git a/juick-xmpp/src/main/java/com/juick/components/s2s/StanzaListener.java b/juick-xmpp/src/main/java/com/juick/components/s2s/StanzaListener.java index 72ca72e8..9aa6b44f 100644 --- a/juick-xmpp/src/main/java/com/juick/components/s2s/StanzaListener.java +++ b/juick-xmpp/src/main/java/com/juick/components/s2s/StanzaListener.java @@ -1,10 +1,11 @@ package com.juick.components.s2s; -import com.juick.xmpp.Stanza; + +import rocks.xmpp.core.stanza.model.Stanza; /** * Created by vitalyster on 07.12.2016. */ public interface StanzaListener { - void stanzaReceived(String name, Stanza xmlValue); + void stanzaReceived(Stanza xmlValue); } -- cgit v1.2.3