/* * * * Licensed to the Apache Software Foundation (ASF) under one or more * * contributor license agreements. The ASF licenses this file to You * * under the Apache License, Version 2.0 (the "License"); you may not * * use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. For additional information regarding * * copyright in this work, please see the NOTICE file in the top level * * directory of this distribution. * */ package org.apache.usergrid.services.notifications.wns; import ar.com.fernandospr.wns.WnsService; import ar.com.fernandospr.wns.model.*; import ar.com.fernandospr.wns.model.builders.WnsBadgeBuilder; import ar.com.fernandospr.wns.model.builders.WnsRawBuilder; import ar.com.fernandospr.wns.model.builders.WnsToastBuilder; import com.sun.jersey.api.client.ClientHandlerException; import org.apache.usergrid.persistence.EntityManager; import org.apache.usergrid.persistence.entities.Notification; import org.apache.usergrid.persistence.entities.Notifier; import org.apache.usergrid.services.ServicePayload; import org.apache.usergrid.services.notifications.ProviderAdapter; import org.apache.usergrid.services.notifications.TaskTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Windows Notifications Service adapter to send windows notifications */ public class WNSAdapter implements ProviderAdapter { private static final Logger logger = LoggerFactory.getLogger(WNSAdapter.class); private final EntityManager entityManager; private final Notifier notifier; private final WnsService service; public WNSAdapter(EntityManager entityManager, Notifier notifier) { this.entityManager = entityManager; this.notifier = notifier; this.service = new WnsService(notifier.getSid(), notifier.getApiKey(), notifier.getLogging()); } @Override public void testConnection() throws Exception { WnsToast toast = new WnsToastBuilder().bindingTemplateToastText01("test").build(); try{ //this fails every time due to jax error which is ok service.pushToast("s-1-15-2-2411381248-444863693-3819932088-4077691928-1194867744-112853457-373132695", toast); }catch (ClientHandlerException e){ logger.info("Windows Phone notifier added: " + e.toString()); } } @Override public void sendNotification(String providerId, Object payload, Notification notification, TaskTracker tracker) throws Exception { try { List<TranslatedNotification> translatedNotifications = ( List<TranslatedNotification>) payload; for(TranslatedNotification translatedNotification : translatedNotifications) { // set the optional TTL value used when pushing notifications WnsNotificationRequestOptional opt = new WnsNotificationRequestOptional(); if(notification.getExpireTTLSeconds()>0) { opt.ttl = String.valueOf(notification.getExpireTTLSeconds()); } switch (translatedNotification.getType()) { case "toast": WnsToast toast = new WnsToastBuilder().bindingTemplateToastText01(translatedNotification.getMessage().toString()).build(); service.pushToast(providerId, opt, toast); break; case "badge": WnsBadge badge; if (translatedNotification.getMessage() instanceof Integer) { badge = new WnsBadgeBuilder().value((Integer) translatedNotification.getMessage()).build(); } else { badge = new WnsBadgeBuilder().value(translatedNotification.getMessage().toString()).build(); } service.pushBadge(providerId, opt, badge); break; case "raw": Object message = translatedNotification.getMessage(); if(message instanceof String) { WnsRaw raw = new WnsRawBuilder().stream(((String) message).getBytes()).build(); // set additional optional parameter for raw notifications opt.cachePolicy = "cache"; opt.requestForStatus = "true"; WnsNotificationResponse response = service.pushRaw(providerId, opt, raw); if (!response.notificationStatus.equals("received")) { // https://msdn.microsoft.com/en-us/library/windows/apps/hh465435.aspx#pncodes_x_wns_notification throw new Exception(String.format("Notification failed status:%s, devicesStatus:%s, description:%s, debug flag:%s", response.notificationStatus, response.deviceConnectionStatus, response.errorDescription, response.debugTrace)); } }else{ throw new IllegalArgumentException("You must send a string in the raw body. instead got this: " + message.getClass().getName()); } break; default: throw new IllegalArgumentException(translatedNotification.getType() + " does not match a valid notification type (toast,badge)."); } } tracker.completed(); } catch (Exception e) { tracker.failed(0,e.toString()); logger.error("Failed to send notification",e); } } @Override public void doneSendingNotifications() throws Exception { } @Override public void removeInactiveDevices() throws Exception { } @Override public Object translatePayload(Object payload) throws Exception { //TODO: allow for badges and toasts at same time List<TranslatedNotification> translatedNotifications = new ArrayList<>(); if (payload instanceof Map) { //{payloads:{winphone:{toast:"mymessage",badge:1}}} Map<String, Object> map = (Map<String, Object>) payload; if (map.containsKey("toast")) { translatedNotifications.add(new TranslatedNotification(map.get("toast").toString(), "toast")); } if (map.containsKey("badge")) { translatedNotifications.add(new TranslatedNotification(map.get("badge"), "badge")); } if (map.containsKey("raw")) { translatedNotifications.add(new TranslatedNotification(map.get("raw"), "raw")); } } else { //{payloads:{winphone:"mymessage"}} //make it a toast if its just a string if (payload instanceof String) { translatedNotifications.add(new TranslatedNotification( (String) payload,"toast")); }else{ throw new IllegalArgumentException("format is messed up"); } } return translatedNotifications; } @Override public void validateCreateNotifier(ServicePayload payload) throws Exception { String apiKey = payload.getStringProperty("apiKey"); String sid = payload.getStringProperty("sid"); Object logging = payload.getProperty("logging"); if(sid == null){ throw new IllegalArgumentException("sid is missing"); } if(logging == null){ throw new IllegalArgumentException("logging is missing"); } if(apiKey == null){ throw new IllegalArgumentException("apiKey is missing"); } } @Override public void stop() { //Do nothing } @Override public Notifier getNotifier() { return notifier; } }