All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.aerogear.unifiedpush.message.sender.WNSPushNotificationSender Maven / Gradle / Ivy

There is a newer version: 2.5.0
Show newest version
/**
 * 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