aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2016-01-26 20:23:44 +0300
committerGravatar Vitaly Takmazov2016-01-26 20:23:44 +0300
commitb9d7b0f0379d0e824bf23a98421a32b585a48ed7 (patch)
tree185d835c3f71c05a40d78b472340f0b85b148376
parentd5b637c358a05965435716ba366f141eb1f61142 (diff)
parentec5a8e1964ac294dcad3968c3216a414d95fd176 (diff)
Merge remote-tracking branch 'bitbucket/develop' into develop
-rw-r--r--build.gradle2
-rw-r--r--src/main/java/com/juick/PushComponent.java163
-rw-r--r--src/main/webapp/WEB-INF/juick.conf.example1
3 files changed, 93 insertions, 73 deletions
diff --git a/build.gradle b/build.gradle
index 0ab1e759..8d7735a3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -61,6 +61,8 @@ dependencies {
compile 'com.ganyo:gcm-server:1.0.+'
compile 'com.notnoop.apns:apns:1.0.0.Beta6'
compile 'com.github.scribejava:scribejava-apis:2.0.1'
+ compile 'org.apache.httpcomponents:httpclient:4.5.1'
+ compile 'org.json:json:20151123'
providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
runtime 'mysql:mysql-connector-java:5.1.37'
def tomcatVersion = '7.0.+'
diff --git a/src/main/java/com/juick/PushComponent.java b/src/main/java/com/juick/PushComponent.java
index 533ca086..4dd78286 100644
--- a/src/main/java/com/juick/PushComponent.java
+++ b/src/main/java/com/juick/PushComponent.java
@@ -32,6 +32,18 @@ import com.juick.xmpp.StreamComponent;
import com.juick.xmpp.extensions.JuickMessage;
import com.notnoop.apns.APNS;
import com.notnoop.apns.ApnsService;
+import org.apache.http.Consts;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONObject;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
@@ -39,18 +51,12 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.HttpURLConnection;
import java.net.Socket;
-import java.net.URL;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Properties;
+import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
@@ -66,6 +72,7 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe
private static Logger logger = Logger.getLogger(PushComponent.class.getName());
private ExecutorService executorService;
+ String wns_application_sip;
String wns_client_secret;
Connection sql;
Socket socket;
@@ -90,6 +97,7 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe
conf.getProperty("mysql_password", ""), conf.getProperty("mysql_database", ""));
setupXmppComponent(new JID("", conf.getProperty("push_jid"), ""), conf.getProperty("xmpp_host", "localhost"),
Integer.parseInt(conf.getProperty("xmpp_port", "5347")), conf.getProperty("push_xmpp_password", ""));
+ wns_application_sip = conf.getProperty("wns_application_sip", "");
wns_client_secret = conf.getProperty("wns_client_secret", "");
} catch (IOException e) {
logger.log(Level.SEVERE, e.getMessage(), e);
@@ -232,35 +240,40 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe
urls = PushQueries.getWinPhoneSubscribers(sql, senderID);
}
- if (!urls.isEmpty()) {
- String text1 = "@" + jmsg.getUser().getUName();
- if (!jmsg.Tags.isEmpty()) {
- text1 += ":" + XmlUtils.escape(jmsg.getTagsString());
- }
- String text2 = XmlUtils.escape(jmsg.getText());
- String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
- + "<toast>"
- + "<visual>"
- + "<binding template=\"ToastText02\">"
- + "<text id=\"1\">" + text1 + "</text>"
- + "<text id=\"2\">" + text2 + "</text>"
- //+ "<image id=\"3\" src=\"http://i.juick.com/as/" + jmsg.User.UID + ".png\" />" // todo: user avatar
- + "</binding>"
- + "</visual>"
- + "<commands>"
- + "<command arguments=\"?mid=" + jmsg.getMID() + "\" />"
- + "</commands>"
- + "</toast>";
- logger.fine(xml);
- for (int i = 0; i < urls.size(); i++) {
- String url = urls.get(i);
- logger.info("WNS: " + url);
- sendWNS(url, xml);
- }
- } else {
+
+ if (urls.isEmpty()) {
logger.info("WNS: no recipients");
+ } else {
+ try {
+ String wnsToken = getWnsAccessToken();
+ String text1 = "@" + jmsg.getUser().getUName();
+ if (!jmsg.Tags.isEmpty()) {
+ text1 += ":" + XmlUtils.escape(jmsg.getTagsString());
+ }
+ String text2 = XmlUtils.escape(jmsg.getText());
+ String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ + "<toast>"
+ + "<visual>"
+ + "<binding template=\"ToastText02\">"
+ + "<text id=\"1\">" + text1 + "</text>"
+ + "<text id=\"2\">" + text2 + "</text>"
+ //+ "<image id=\"3\" src=\"http://i.juick.com/as/" + jmsg.User.UID + ".png\" />" // todo: user avatar
+ + "</binding>"
+ + "</visual>"
+ + "<commands>"
+ + "<command arguments=\"?mid=" + jmsg.getMID() + "\" />"
+ + "</commands>"
+ + "</toast>";
+ logger.fine(xml);
+ for (int i = 0; i < urls.size(); i++) {
+ String url = urls.get(i);
+ logger.info("WNS: " + url);
+ sendWNS(wnsToken, url, xml);
+ }
+ } catch (IOException e) {
+ logger.log(Level.SEVERE, "WNS: ", e);
+ }
}
-
/*** iOS ***/
List<String> tokens;
@@ -286,48 +299,52 @@ public class PushComponent implements ServletContextListener, Stream.StreamListe
}
}
- public boolean sendWNS(String url, String xml) {
- boolean ret = false;
- try {
- HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
- conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
- String token = "Bearer " + wns_client_secret;
- conn.setRequestProperty("Authorization", token);
- conn.setRequestProperty("X-WNS-Type", "wns/toast"); // todo: mb use "wns/badge" or "wns/tile"
- conn.setUseCaches(false);
- conn.setDoInput(true);
- conn.setDoOutput(true);
- conn.setRequestMethod("POST");
- conn.connect();
-
- OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
- wr.write(xml);
- wr.close();
-
- if (conn.getResponseCode() == 200) {
- ret = streamToString(conn.getInputStream()) != null;
- }
-
- conn.disconnect();
- } catch (Exception e) {
- logger.log(Level.SEVERE, "sendWNS error: ", e);
+ String getWnsAccessToken() throws IOException {
+ HttpClient client = HttpClientBuilder.create().build();
+ String url = "https://login.live.com/accesstoken.srf";
+ List<NameValuePair> formParams = new ArrayList<NameValuePair>();
+ formParams.add(new BasicNameValuePair("grant_type", "client_credentials"));
+ formParams.add(new BasicNameValuePair("client_id", wns_application_sip));
+ formParams.add(new BasicNameValuePair("client_secret", wns_client_secret));
+ formParams.add(new BasicNameValuePair("scope", "notify.windows.com"));
+ UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
+ HttpPost httppost = new HttpPost(url);
+ httppost.setEntity(entity);
+ HttpResponse response = client.execute(httppost);
+ int statusCode = response.getStatusLine().getStatusCode();
+ String responseContent = EntityUtils.toString(response.getEntity(), Consts.UTF_8);
+ JSONObject json = new JSONObject(responseContent);
+ if(statusCode != 200) {
+ throw new IOException(json.opt("error") + ": " + json.opt("error_description"));
}
- return ret;
+ 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");
}
- public String streamToString(InputStream is) {
- try {
- BufferedReader buf = new BufferedReader(new InputStreamReader(is));
- StringBuilder str = new StringBuilder();
- String line;
- do {
- line = buf.readLine();
- str.append(line).append("\n");
- } while (line != null);
- return str.toString();
- } catch (Exception e) {
- logger.severe("streamToString: " + e.toString());
+ void sendWNS(String wnsToken, String url, String xml) throws IOException {
+ HttpClient client = HttpClientBuilder.create().build();
+ StringEntity entity = new StringEntity(xml, Consts.UTF_8);
+ HttpPost httpPost = new HttpPost(url);
+ httpPost.setHeader("Content-Type", "text/xml");
+ httpPost.setHeader("Authorization", wnsToken);
+ httpPost.setHeader("X-WNS-Type", "wns/toast");
+ httpPost.setEntity(entity);
+ HttpResponse response = client.execute(httpPost);
+ int statusCode = response.getStatusLine().getStatusCode();
+ if(statusCode != 200) {
+ String headersContent = stringifyWnsHttpHeaders(response.getAllHeaders());
+ throw new IOException(headersContent);
}
- return null;
+ }
+
+ static String stringifyWnsHttpHeaders(Header[] allHeaders) {
+ String[] wnsHeaders = Arrays.stream(allHeaders)
+ .filter(x -> x.getName().startsWith("X-WNS-") || x.getName().startsWith("WWW-"))
+ .map(x -> x.getName() + ": " + x.getValue())
+ .toArray(String[]::new);
+ return String.join("\n", wnsHeaders);
}
}
diff --git a/src/main/webapp/WEB-INF/juick.conf.example b/src/main/webapp/WEB-INF/juick.conf.example
index 8c897f3a..c0812b61 100644
--- a/src/main/webapp/WEB-INF/juick.conf.example
+++ b/src/main/webapp/WEB-INF/juick.conf.example
@@ -1,4 +1,5 @@
mysql_username=username
xmpp_password=secret
sape_user=usertoken
+wns_application_sip=ms-app://x-1-11-1-1111111111-...
wns_client_secret=secret \ No newline at end of file