protected void handle(final APIAttachBackupStorageToZoneMsg msg) {
    final APIAttachBackupStorageToZoneEvent evt =
        new APIAttachBackupStorageToZoneEvent(msg.getId());
    final BackupStorageVO svo = dbf.findByUuid(msg.getBackupStorageUuid(), BackupStorageVO.class);

    String err = extpEmitter.preAttach(svo, msg.getZoneUuid());
    if (err != null) {
      evt.setErrorCode(errf.instantiateErrorCode(BackupStorageErrors.ATTACH_ERROR, err));
      bus.publish(evt);
      return;
    }

    extpEmitter.beforeAttach(svo, msg.getZoneUuid());
    attachHook(
        msg.getZoneUuid(),
        new Completion(msg) {
          @Override
          public void success() {
            BackupStorageZoneRefVO rvo = new BackupStorageZoneRefVO();
            rvo.setBackupStorageUuid(svo.getUuid());
            rvo.setZoneUuid(msg.getZoneUuid());
            dbf.persist(rvo);

            refreshVO();
            extpEmitter.afterAttach(self, msg.getZoneUuid());

            evt.setInventory(getSelfInventory());
            logger.debug(
                String.format(
                    "successfully attached backup storage[uuid:%s, name:%s]",
                    self.getUuid(), self.getName()));
            bus.publish(evt);
          }

          @Override
          public void fail(ErrorCode errorCode) {
            logger.warn(errorCode.toString());
            extpEmitter.failToAttach(svo, msg.getZoneUuid());
            evt.setErrorCode(
                errf.instantiateErrorCode(BackupStorageErrors.ATTACH_ERROR, errorCode));
            bus.publish(evt);
          }
        });
  }