private void pushChannel( IPushChannel channel, IPreferences prefs, Notification notification, boolean ignoreFrequency) throws PushException, RenderException { IPushChannelPreferences cPrefs = prefs.getChannelPrefs().get(channel.getId()); if (cPrefs == null) { cPrefs = channel.newDefaultPreferences(); if (cPrefs == null) { // don't flood user after he configures this channel throw new PushException("channel not configured for user", false); } } if (!channel.getNotificationTypes().contains(notification.getType())) { // channel not applicable for type throw new PushException("channel not applicable for type " + notification.getType(), false); } Dispatch dispatch = _dispatchService.create(notification, prefs, cPrefs); if (!channel.isConfigured(dispatch.getParams())) { // don't flood user after he configures this channel throw new PushException("channel not configured for user", false); } if (!ignoreFrequency && !Frequency.INSTANT.equals(cPrefs.getFrequency())) { // temporary as other dispatcher will handle this throw new PushException("channel not configured for this frequency", true); } channel.push(dispatch); }
private void recordPushAttempt(Notification notification, @Nonnull PushResultMessage rm) { if (rm.getResult() == PushResult.SUCCESS) { notification.setPushState(PushState.PUSHED); notification.setPushDate(new Date()); notification.setPushErrorMessage(rm.getMessage()); } else { int errorCount = notification.recordPushError(rm.getMessage()); if (errorCount > _maxErrorCount || rm.getResult() == PushResult.PERSISTENT_ERROR) { notification.setPushState(PushState.UNDELIVERABLE); notification.setPushDate(new Date()); } else { notification.setPushState(PushState.QUEUED); notification.setPushDate(new Date(System.currentTimeMillis() + waitAfter(errorCount))); } } _notificationDAO.update(notification); }
@Nonnull private PushResultMessage push(@Nonnull Notification notification, boolean ignoreFrequency) { IPreferences prefs; final String unknownChannel = notification.getParams().get(INotifyService.NOTIFY_UNKNOWN); if (unknownChannel != null) { prefs = new Preferences().setUserId(notification.getUserId()); } else { prefs = _preferencesDAO.getPreferences(notification.getUserId()); } if (prefs == null) { log.warn("can't push to unknown user " + notification.getUserId()); return PushResultMessage.persistent("unknown user " + notification.getUserId()); } Set<String> successChannels = Sets.newHashSet(); Map<String, String> temporaryChannels = Maps.newHashMap(); Map<String, String> persistentChannels = Maps.newHashMap(); Iterable<IPushChannel> channels = Iterables.filter( _pushChannels, new Predicate<IPushChannel>() { @Override public boolean apply(IPushChannel channel) { return unknownChannel == null || channel.getId().equals(unknownChannel); } }); for (IPushChannel channel : channels) { try { pushChannel(channel, prefs, notification, ignoreFrequency); successChannels.add(channel.getId()); } catch (PushException e) { if (e.isTemporaryError()) { temporaryChannels.put(channel.getId(), e.getMessage()); } else { persistentChannels.put(channel.getId(), e.getMessage()); } if (_errorListener != null) { _errorListener.error(notification, channel, e); } else { log.info( "failed to deliver notification " + notification + " on channel " + channel.getId() + ": " + ExceptionUtils.getAllMessages(e)); } } catch (RenderException e) { log.error("failed to render notification " + notification, e); temporaryChannels.put(channel.getId(), ExceptionUtils.getAllMessages(e)); } } if (successChannels.size() > 0) { return PushResultMessage.success("channels: " + successChannels); } else if (temporaryChannels.size() > 0) { return PushResultMessage.temporary("temporary error, channels: " + temporaryChannels); } else if (persistentChannels.size() > 0) { return PushResultMessage.persistent("persistent error, channels: " + persistentChannels); } else { return PushResultMessage.temporary("no allowed channels available"); } }