public GCMSender(AccountsManager accountsManager, String signalKey, DirectoryQueue directoryQueue) { this.accountsManager = accountsManager; this.signalSender = new Sender(signalKey, 50); this.directoryQueue = directoryQueue; }
@Override public void onSuccess(Result result) { if (result.isUnregistered() || result.isInvalidRegistrationId()) { handleBadRegistration(result); } else if (result.hasCanonicalRegistrationId()) { handleCanonicalRegistrationId(result); } else if (!result.isSuccess()) { handleGenericError(result); } else { success.mark(); } }
@Override public void stop() throws IOException { this.signalSender.stop(); this.executor.shutdown(); }
public void sendMessage(GcmMessage message) { Message.Builder builder = Message.newBuilder() .withDestination(message.getGcmId()) .withPriority("high"); String key = message.isReceipt() ? "receipt" : "notification"; Message request = builder.withDataPart(key, "").build(); ListenableFuture<Result> future = signalSender.send(request, message); markOutboundMeter(key); Futures.addCallback(future, new FutureCallback<Result>() { @Override public void onSuccess(Result result) { if (result.isUnregistered() || result.isInvalidRegistrationId()) { handleBadRegistration(result); } else if (result.hasCanonicalRegistrationId()) { handleCanonicalRegistrationId(result); } else if (!result.isSuccess()) { handleGenericError(result); } else { success.mark(); } } @Override public void onFailure(Throwable throwable) { logger.warn("GCM Failed: " + throwable); } }, executor); }
private void handleGenericError(Result result) { GcmMessage message = (GcmMessage)result.getContext(); logger.warn(String.format("Unrecoverable Error ::: (error=%s), (gcm_id=%s), " + "(destination=%s), (device_id=%d)", result.getError(), message.getGcmId(), message.getNumber(), message.getDeviceId())); failure.mark(); }
private void handleCanonicalRegistrationId(Result result) { GcmMessage message = (GcmMessage)result.getContext(); logger.warn(String.format("Actually received 'CanonicalRegistrationId' ::: (canonical=%s), (original=%s)", result.getCanonicalRegistrationId(), message.getGcmId())); Optional<Account> account = getAccountForEvent(message); if (account.isPresent()) { Device device = account.get().getDevice(message.getDeviceId()).get(); device.setGcmId(result.getCanonicalRegistrationId()); accountsManager.update(account.get()); } canonical.mark(); }
private Result parseResult(String body) throws IOException { List<GcmResponseEntity> responseList = objectMapper.readValue(body, GcmResponseListEntity.class) .getResults(); if (responseList == null || responseList.size() == 0) { throw new IOException("Empty response list!"); } GcmResponseEntity responseEntity = responseList.get(0); return new Result(this.requestContext, responseEntity.getCanonicalRegistrationId(), responseEntity.getMessageId(), responseEntity.getError()); } }
@Override public void completed(HttpResponse result) { try { String responseBody = EntityUtils.toString(result.getEntity()); switch (result.getStatusLine().getStatusCode()) { case 400: future.setException(new InvalidRequestException()); break; case 401: future.setException(new AuthenticationFailedException()); break; case 204: case 200: future.set(parseResult(responseBody)); break; default: future.setException(new ServerFailedException("Bad status: " + result.getStatusLine().getStatusCode())); } } catch (IOException e) { future.setException(e); } }
/** * Asynchronously send a message. * * @param message The message to send. * @return A future. */ public ListenableFuture<Result> send(Message message) { return send(message, null); }
private void handleBadRegistration(Result result) { GcmMessage message = (GcmMessage)result.getContext(); logger.warn("Got GCM unregistered notice! " + message.getGcmId()); Optional<Account> account = getAccountForEvent(message); if (account.isPresent()) { Device device = account.get().getDevice(message.getDeviceId()).get(); device.setGcmId(null); device.setFetchesMessages(false); accountsManager.update(account.get()); if (!account.get().isActive()) { directoryQueue.deleteRegisteredUser(account.get().getNumber()); } } unregistered.mark(); }
@Override public ListenableFuture<Result> call(RetryContext context) throws Exception { SettableFuture<Result> future = SettableFuture.create(); HttpPost request = new HttpPost(url); request.setHeader("Authorization", authorizationHeader); request.setEntity(new StringEntity(message.serialize(), ContentType.parse("application/json"))); client.execute(request, new ResponseHandler(future, requestContext)); return future; } });
/** * Construct a new Message using a Builder. * @return A new Builder. */ public static Builder newBuilder() { return new Builder(); }
@Override public void cancelled() { future.setException(new ServerFailedException("Canceled!")); }
/** * Construct a message object. * * @return An immutable message object, as configured by this builder. */ public Message build() { if (registrationIds.isEmpty()) { throw new IllegalArgumentException("You must specify a destination!"); } return new Message(collapseKey, ttl, delayWhileIdle, data, registrationIds, priority); } }
@Override public void sendMessage(GcmMessage message) { Message.Builder builder = Message.newBuilder() .withDestination(message.getGcmId()) .withPriority("high"); Message request = builder.withDataPart(key, message.getMessage()).build(); future = signalSender.send(request, message); markOutboundMeter(key); } else { Message request = builder.withDataPart("signal", message.getMessage()).build(); future = redphoneSender.send(request, message); markOutboundMeter("signal");
@Override public void onSuccess(Result result) { if (result.isUnregistered() || result.isInvalidRegistrationId()) { handleBadRegistration(result); } else if (result.hasCanonicalRegistrationId()) { handleCanonicalRegistrationId(result); } else if (!result.isSuccess()) { handleGenericError(result); } else { success.mark(); } }
private void handleGenericError(Result result) { GcmMessage message = (GcmMessage)result.getContext(); logger.warn(String.format("Unrecoverable Error ::: (error=%s), (gcm_id=%s), " + "(destination=%s), (device_id=%d)", result.getError(), message.getGcmId(), message.getNumber(), message.getDeviceId())); failure.mark(); }
private void handleBadRegistration(Result result) { GcmMessage message = (GcmMessage)result.getContext(); logger.warn("Got GCM unregistered notice! " + message.getGcmId()); unregisteredQueue.put(new UnregisteredEvent(message.getGcmId(), null, message.getNumber(), message.getDeviceId(), System.currentTimeMillis())); unregistered.mark(); }