Example #1
0
  private void removeIntent(IntentService intentService, Intent intent) {
    IntentListener listener = null;
    Key key = intent.key();
    final CountDownLatch withdrawLatch, purgeLatch;
    if (purgeAfterRemove || sync) {
      // set up latch and listener to track uninstall progress
      withdrawLatch = new CountDownLatch(1);
      purgeLatch = purgeAfterRemove ? new CountDownLatch(1) : null;
      listener =
          (IntentEvent event) -> {
            if (Objects.equals(event.subject().key(), key)) {
              if (event.type() == IntentEvent.Type.WITHDRAWN
                  || event.type() == IntentEvent.Type.FAILED) {
                withdrawLatch.countDown();
              } else if (purgeAfterRemove && event.type() == IntentEvent.Type.PURGED) {
                purgeLatch.countDown();
              }
            }
          };
      intentService.addListener(listener);
    } else {
      purgeLatch = null;
      withdrawLatch = null;
    }

    // request the withdraw
    intentService.withdraw(intent);

    if (purgeAfterRemove || sync) {
      try { // wait for withdraw event
        withdrawLatch.await(5, TimeUnit.SECONDS);
      } catch (InterruptedException e) {
        print("Timed out waiting for intent {} withdraw", key);
      }
      // double check the state
      IntentState state = intentService.getIntentState(key);
      if (purgeAfterRemove && (state == WITHDRAWN || state == FAILED)) {
        intentService.purge(intent);
      }
      if (sync) { // wait for purge event
        /* TODO
           Technically, the event comes before map.remove() is called.
           If we depend on sync and purge working together, we will
           need to address this.
        */
        try {
          purgeLatch.await(5, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
          print("Timed out waiting for intent {} purge", key);
        }
      }
    }

    if (listener != null) {
      // clean up the listener
      intentService.removeListener(listener);
    }
  }
Example #2
0
  /**
   * Uninstalls a single intent by Id.
   *
   * @param appId the Application ID
   * @param keyString the Intent key value to look up
   */
  @DELETE
  @Path("{appId}/{key}")
  public void deleteIntentById(
      @PathParam("appId") String appId, @PathParam("key") String keyString) {
    final ApplicationId app = get(CoreService.class).getAppId(appId);

    Intent intent = get(IntentService.class).getIntent(Key.of(keyString, app));
    IntentService service = get(IntentService.class);

    if (intent == null) {
      intent = service.getIntent(Key.of(Long.decode(keyString), app));
    }
    if (intent == null) {
      // No such intent.  REST standards recommend a positive status code
      // in this case.
      return;
    }

    Key key = intent.key();

    // set up latch and listener to track uninstall progress
    CountDownLatch latch = new CountDownLatch(1);

    IntentListener listener = new DeleteListener(key, latch);
    service.addListener(listener);

    try {
      // request the withdraw
      service.withdraw(intent);

      try {
        latch.await(WITHDRAW_EVENT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
      } catch (InterruptedException e) {
        log.info("REST Delete operation timed out waiting for intent {}", key);
      }
      // double check the state
      IntentState state = service.getIntentState(key);
      if (state == WITHDRAWN || state == FAILED) {
        service.purge(intent);
      }

    } finally {
      // clean up the listener
      service.removeListener(listener);
    }
  }