org.jboss.aerogear.unifiedpush.message.sender.WNSPushNotificationSender Maven / Gradle / Ivy
/**
* JBoss, Home of Professional Open Source
* Copyright Red Hat, Inc., and individual contributors.
*
* Licensed 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.
*/
package org.jboss.aerogear.unifiedpush.message.sender;
import ar.com.fernandospr.wns.WnsService;
import ar.com.fernandospr.wns.exceptions.WnsException;
import ar.com.fernandospr.wns.model.WnsBadge;
import ar.com.fernandospr.wns.model.WnsNotificationRequestOptional;
import ar.com.fernandospr.wns.model.WnsNotificationResponse;
import ar.com.fernandospr.wns.model.WnsRaw;
import ar.com.fernandospr.wns.model.WnsTile;
import ar.com.fernandospr.wns.model.WnsToast;
import ar.com.fernandospr.wns.model.builders.WnsAbstractBuilder;
import ar.com.fernandospr.wns.model.builders.WnsBadgeBuilder;
import ar.com.fernandospr.wns.model.builders.WnsRawBuilder;
import ar.com.fernandospr.wns.model.builders.WnsTileBuilder;
import ar.com.fernandospr.wns.model.builders.WnsToastBuilder;
import org.jboss.aerogear.unifiedpush.api.Variant;
import org.jboss.aerogear.unifiedpush.api.VariantType;
import org.jboss.aerogear.unifiedpush.api.WindowsWNSVariant;
import org.jboss.aerogear.unifiedpush.message.InternalUnifiedPushMessage;
import org.jboss.aerogear.unifiedpush.message.Message;
import org.jboss.aerogear.unifiedpush.message.UnifiedPushMessage;
import org.jboss.aerogear.unifiedpush.message.windows.Windows;
import org.jboss.aerogear.unifiedpush.service.ClientInstallationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.UriBuilder;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@SenderType(VariantType.WINDOWS_WNS)
public class WNSPushNotificationSender implements PushNotificationSender {
private final Logger logger = LoggerFactory.getLogger(WNSPushNotificationSender.class);
private static final String CORDOVA = "cordova";
static final String CORDOVA_PAGE = "/Plugins/aerogear-cordova-push/P.xaml";
private String pushMessageInformationId;
@Inject
private ClientInstallationService clientInstallationService;
@Override
public void sendPushMessage(Variant variant, Collection clientIdentifiers, UnifiedPushMessage pushMessage, String pushMessageInformationId, NotificationSenderCallback senderCallback) {
setPushMessageInformationId(pushMessageInformationId);
// no need to send empty list
if (clientIdentifiers.isEmpty()) {
return;
}
final WindowsWNSVariant windowsVariant = (WindowsWNSVariant) variant;
WnsService wnsService = new WnsService(windowsVariant.getSid(), windowsVariant.getClientSecret(), false);
Set expiredClientIdentifiers = new HashSet<>(clientIdentifiers.size());
ArrayList channelUris = new ArrayList<>(clientIdentifiers);
Message message = pushMessage.getMessage();
try {
WnsNotificationRequestOptional optional = new WnsNotificationRequestOptional();
int ttl = pushMessage.getConfig().getTimeToLive();
if (ttl != -1) {
optional.ttl = String.valueOf(ttl);
}
final List responses;
if (message.getWindows().getType() != null) {
switch (message.getWindows().getType()) {
case toast:
responses = wnsService.pushToast(channelUris, optional, createToastMessage(message));
break;
case badge:
responses = wnsService.pushBadge(channelUris, optional, createBadgeMessage(message));
break;
case raw:
responses = wnsService.pushRaw(channelUris, optional, createRawMessage(message));
break;
case tile:
responses = wnsService.pushTile(channelUris, optional, createTileMessage(message));
break;
default:
throw new IllegalArgumentException("unknown type: " + message.getWindows().getType());
}
} else {
responses = wnsService.pushToast(channelUris, optional, createSimpleToastMessage(message));
}
logger.info(String.format("Sent push notification to WNS for %d tokens", channelUris.size()));
expiredClientIdentifiers.addAll(responses.stream().filter(response -> response.code == HttpServletResponse.SC_GONE).map(response -> response.channelUri).collect(Collectors.toList()));
if (!expiredClientIdentifiers.isEmpty()) {
logger.info(String.format("Deleting '%d' expired WNS installations", expiredClientIdentifiers.size()));
clientInstallationService.removeInstallationsForVariantByDeviceTokens(variant.getVariantID(), expiredClientIdentifiers);
}
logger.debug("Message to WNS has been submitted");
senderCallback.onSuccess();
} catch (WnsException | IllegalArgumentException exception) {
senderCallback.onError(exception.getMessage());
}
}
WnsToast createToastMessage(Message message) {
final WnsToastBuilder builder = new WnsToastBuilder();
Windows windows = message.getWindows();
if (windows.getDuration() != null) {
builder.duration(windows.getDuration().toString());
}
builder.audioSrc(message.getSound());
builder.launch(createLaunchParam(message.getWindows().getPage(), message.getAlert(), message.getUserData(), getPushMessageInformationId()));
createMessage(message, windows.getToastType().toString(), builder);
return builder.build();
}
private static WnsBadge createBadgeMessage(Message message) {
final WnsBadgeBuilder builder = new WnsBadgeBuilder();
Windows windows = message.getWindows();
if (windows.getBadge() != null) {
builder.value(windows.getBadge().toString());
} else {
builder.value(message.getBadge());
}
return builder.build();
}
private static WnsRaw createRawMessage(Message message) {
final WnsRawBuilder builder = new WnsRawBuilder();
builder.stream(message.getAlert().getBytes());
return builder.build();
}
WnsTile createTileMessage(Message message) {
final WnsTileBuilder builder = new WnsTileBuilder();
createMessage(message, message.getWindows().getTileType().toString(), builder);
return builder.build();
}
private static void createMessage(Message message, String type, WnsAbstractBuilder builder) {
Windows windows = message.getWindows();
List param = new ArrayList<>(windows.getImages());
param.add(message.getAlert());
param.addAll(windows.getTextFields());
createTemplate(builder, type, param);
}
private static void createTemplate(WnsAbstractBuilder builder, String type, List param) {
try {
Method[] methods = builder.getClass().getMethods();
for (Method method : methods) {
if (method.getName().equals("bindingTemplate" + type)) {
int methodArgs = method.getParameterTypes().length;
if (methodArgs == param.size()) {
method.invoke(builder, (Object[]) param.toArray(new String[param.size()]));
} else {
throw new IllegalArgumentException("this template needs " + methodArgs
+ " fields, but you specified " + param.size());
}
}
}
} catch (InvocationTargetException e) {
throw new RuntimeException("error thrown while invoking template build method: " + type, e);
} catch (IllegalAccessException e) {
throw new RuntimeException("something wrong with the permissions of this method", e);
}
}
WnsToast createSimpleToastMessage(Message message) {
final WnsToastBuilder builder = new WnsToastBuilder().bindingTemplateToastText01(message.getAlert());
final Map data = message.getUserData();
builder.launch(createLaunchParam(message.getWindows().getPage(), message.getAlert(), data, getPushMessageInformationId()));
return builder.build();
}
public String getPushMessageInformationId() {
return pushMessageInformationId;
}
public void setPushMessageInformationId(String pushMessageInformationId) {
this.pushMessageInformationId = pushMessageInformationId;
}
static String createLaunchParam(String page, String message, Map data, String pushMessageInformationId) {
final UriBuilder uriBuilder = UriBuilder.fromPath("");
data.forEach(uriBuilder::queryParam);
if (message != null) {
uriBuilder.queryParam("message", message);
}
//add aerogear-push-id
uriBuilder.queryParam(InternalUnifiedPushMessage.PUSH_MESSAGE_ID, pushMessageInformationId);
final String query = uriBuilder.build().getQuery();
return (CORDOVA.equals(page) ? CORDOVA_PAGE : page) + (query != null ? ("?" + query) : "");
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy