package com.juick.components; import com.fasterxml.jackson.databind.ObjectMapper; import com.juick.components.mpns.MPNSError; import com.juick.components.mpns.MPNSToken; import org.apache.http.*; 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.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import javax.annotation.PostConstruct; import javax.inject.Inject; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * Created by vital on 29.03.2017. */ public class MPNSClient { private static Logger logger = LoggerFactory.getLogger(MPNSClient.class); private String accessToken; private NotificationClientListener listener; @Inject private ObjectMapper jsonMapper; @Value("${wns_application_sip}") private String applicationSip; @Value("${wns_client_secret}") private String applicationSecret; @PostConstruct public void authenticate() throws IOException { HttpClient client = HttpClientBuilder.create().build(); String url = "https://login.live.com/accesstoken.srf"; List formParams = new ArrayList<>(); formParams.add(new BasicNameValuePair("grant_type", "client_credentials")); formParams.add(new BasicNameValuePair("client_id", applicationSip)); formParams.add(new BasicNameValuePair("client_secret", applicationSecret)); 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); if (statusCode != HttpStatus.SC_OK) { MPNSError error = jsonMapper.readValue(responseContent, MPNSError.class); throw new IOException(error.getError() + ": " + error.getErrorDescription()); } MPNSToken token = jsonMapper.readValue(responseContent, MPNSToken.class); if (token.getTokenType().length() >= 1) { token.setTokenType(Character.toUpperCase(token.getTokenType().charAt(0)) + token.getTokenType().substring(1)); } accessToken = token.getTokenType() + " " + token.getAccessToken(); logger.info("MPNS authenticated"); } void sendNotification(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); httpPost.setHeader("Content-Type", "text/xml"); httpPost.setHeader("Authorization", accessToken); httpPost.setHeader("X-WNS-Type", "wns/toast"); httpPost.setEntity(entity); HttpResponse response = client.execute(httpPost); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { if (statusCode == HttpStatus.SC_GONE) { // expired logger.info("{} is scheduled to remove", url); listener.invalidToken("mpns", url); } else { String headersContent = stringifyWnsHttpHeaders(response.getAllHeaders()); throw new IOException(headersContent); } } } private String stringifyWnsHttpHeaders(final Header[] allHeaders) { return Arrays.stream(allHeaders) .filter(x -> x.getName().startsWith("X-WNS-") || x.getName().startsWith("WWW-")) .map(x -> x.getName() + ": " + x.getValue()) .collect(Collectors.joining("\n")); } public void setListener(NotificationClientListener listener) { this.listener = listener; } }