@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 Entity updateEntity(ServiceRequest request, EntityRef ref, ServicePayload payload)
      throws Exception {

    validate(ref, payload);

    Notification notification = em.get(ref, Notification.class);

    if ("restart".equals(payload.getProperty("restart"))) { // for emergency
      // use only
      payload.getProperties().clear();
      payload.setProperty("restart", "");
      payload.setProperty("errorMessage", "");
      payload.setProperty("deliver", System.currentTimeMillis() + gracePeriod);

      // once finished, immutable
    } else if (notification.getFinished() != null) {
      throw new ForbiddenServiceOperationException(request, "Notification immutable once sent.");

      // once started, only cancel is allowed
    } else if (notification.getStarted() != null) {
      if (payload.getProperty("canceled") != Boolean.TRUE) {
        throw new ForbiddenServiceOperationException(
            request, "Notification has started. You may only set canceled.");
      }
      payload.getProperties().clear();
      payload.setProperty("canceled", Boolean.TRUE);
    }

    Entity response = super.updateEntity(request, ref, payload);

    Long deliver = (Long) payload.getProperty("deliver");
    if (deliver != null) {
      if (!deliver.equals(notification.getDeliver())) {
        notificationQueueManager.queueNotification((Notification) response, null);
      }
    }
    return response;
  }
 // validate payloads
 private void validate(EntityRef ref, ServicePayload servicePayload) throws Exception {
   Object obj_payloads = servicePayload.getProperty("payloads");
   if (obj_payloads == null && ref == null) {
     throw new RequiredPropertyNotFoundException("notification", "payloads");
   }
   if (obj_payloads != null) {
     if (!(obj_payloads instanceof Map)) {
       throw new IllegalArgumentException("payloads must be a JSON Map");
     }
     final Map<String, Object> payloads = (Map<String, Object>) obj_payloads;
     final Map<Object, Notifier> notifierMap = getNotifierMap(payloads);
     Observable t =
         Observable.from(payloads.entrySet())
             .subscribeOn(Schedulers.io())
             .map(
                 new Func1<Map.Entry<String, Object>, Object>() {
                   @Override
                   public Object call(Map.Entry<String, Object> entry) {
                     String notifierId = entry.getKey();
                     Notifier notifier = notifierMap.get(notifierId);
                     if (notifier == null) {
                       throw new IllegalArgumentException(
                           "notifier \"" + notifierId + "\" not found");
                     }
                     ProviderAdapter providerAdapter =
                         ProviderAdapterFactory.getProviderAdapter(notifier, em);
                     Object payload = entry.getValue();
                     try {
                       return providerAdapter.translatePayload(payload); // validate
                       // specifically to
                       // provider
                     } catch (Exception e) {
                       return e;
                     }
                   }
                 });
     Object e = t.toBlocking().lastOrDefault(null);
     if (e instanceof Throwable) {
       throw new Exception((Exception) e);
     }
   }
 }