private function activateLease(DrydockLease $lease)
 {
     $actual_status = $lease->getStatus();
     if ($actual_status != DrydockLeaseStatus::STATUS_ACQUIRED) {
         throw new PhabricatorWorkerPermanentFailureException(pht('Trying to activate lease from wrong status ("%s").', $actual_status));
     }
     $resource_id = $lease->getResourceID();
     $resource = id(new DrydockResourceQuery())->setViewer($this->getViewer())->withIDs(array($resource_id))->executeOne();
     if (!$resource) {
         throw new PhabricatorWorkerPermanentFailureException(pht('Trying to activate lease on invalid resource ("%s").', $resource_id));
     }
     $resource_status = $resource->getStatus();
     if ($resource_status == DrydockResourceStatus::STATUS_PENDING) {
         // TODO: This is explicitly a temporary failure -- we are waiting for
         // the resource to come up.
         throw new Exception(pht('Resource still activating.'));
     }
     if ($resource_status != DrydockResourceStatus::STATUS_OPEN) {
         throw new PhabricatorWorkerPermanentFailureException(pht('Trying to activate lease on a dead resource (in status "%s").', $resource_status));
     }
     // NOTE: We can race resource destruction here. Between the time we
     // performed the read above and now, the resource might have closed, so
     // we may activate leases on dead resources. At least for now, this seems
     // fine: a resource dying right before we activate a lease on it should not
     // be distinguisahble from a resource dying right after we activate a lease
     // on it. We end up with an active lease on a dead resource either way, and
     // can not prevent resources dying from lightning strikes.
     $blueprint = $resource->getBlueprint();
     $blueprint->activateLease($resource, $lease);
     $this->validateActivatedLease($blueprint, $resource, $lease);
 }
 private function buildPropertyListView(DrydockLease $lease, PhabricatorActionListView $actions)
 {
     $view = new PHUIPropertyListView();
     $view->setActionList($actions);
     switch ($lease->getStatus()) {
         case DrydockLeaseStatus::STATUS_ACTIVE:
             $status = pht('Active');
             break;
         case DrydockLeaseStatus::STATUS_RELEASED:
             $status = pht('Released');
             break;
         case DrydockLeaseStatus::STATUS_EXPIRED:
             $status = pht('Expired');
             break;
         case DrydockLeaseStatus::STATUS_PENDING:
             $status = pht('Pending');
             break;
         case DrydockLeaseStatus::STATUS_BROKEN:
             $status = pht('Broken');
             break;
         default:
             $status = pht('Unknown');
             break;
     }
     $view->addProperty(pht('Status'), $status);
     $view->addProperty(pht('Resource Type'), $lease->getResourceType());
     $view->addProperty(pht('Resource'), $lease->getResourceID());
     $attributes = $lease->getAttributes();
     if ($attributes) {
         $view->addSectionHeader(pht('Attributes'));
         foreach ($attributes as $key => $value) {
             $view->addProperty($key, $value);
         }
     }
     return $view;
 }
 /**
  * Make sure that a lease was really acquired properly.
  *
  * @param DrydockBlueprint Blueprint which created the resource.
  * @param DrydockResource Resource which was acquired.
  * @param DrydockLease The lease which was supposedly acquired.
  * @return void
  * @task lease
  */
 private function validateAcquiredLease(DrydockBlueprint $blueprint, DrydockResource $resource, DrydockLease $lease)
 {
     if (!$lease->isAcquiredLease()) {
         throw new Exception(pht('Blueprint "%s" (of type "%s") is not properly implemented: it ' . 'returned from "%s" without acquiring a lease.', $blueprint->getBlueprintName(), $blueprint->getClassName(), 'acquireLease()'));
     }
     $lease_id = $lease->getResourceID();
     $resource_id = $resource->getID();
     if ($lease_id !== $resource_id) {
         // TODO: Destroy the lease?
         throw new Exception(pht('Blueprint "%s" (of type "%s") is not properly implemented: it ' . 'returned from "%s" with a lease acquired on the wrong resource.', $blueprint->getBlueprintName(), $blueprint->getClassName(), 'acquireLease()'));
     }
 }