Beispiel #1
0
  private void handle(APIDeleteImageMsg msg) {
    final APIDeleteImageEvent evt = new APIDeleteImageEvent(msg.getId());

    final String issuer = ImageVO.class.getSimpleName();
    ImageDeletionStruct struct = new ImageDeletionStruct();
    struct.setImage(ImageInventory.valueOf(self));
    struct.setBackupStorageUuids(msg.getBackupStorageUuids());
    final List<ImageDeletionStruct> ctx = Arrays.asList(struct);
    FlowChain chain = FlowChainBuilder.newSimpleFlowChain();
    chain.setName(String.format("delete-image-%s", msg.getUuid()));
    if (msg.getDeletionMode() == APIDeleteMessage.DeletionMode.Permissive) {
      chain
          .then(
              new NoRollbackFlow() {
                @Override
                public void run(final FlowTrigger trigger, Map data) {
                  casf.asyncCascade(
                      CascadeConstant.DELETION_CHECK_CODE,
                      issuer,
                      ctx,
                      new Completion(trigger) {
                        @Override
                        public void success() {
                          trigger.next();
                        }

                        @Override
                        public void fail(ErrorCode errorCode) {
                          trigger.fail(errorCode);
                        }
                      });
                }
              })
          .then(
              new NoRollbackFlow() {
                @Override
                public void run(final FlowTrigger trigger, Map data) {
                  casf.asyncCascade(
                      CascadeConstant.DELETION_DELETE_CODE,
                      issuer,
                      ctx,
                      new Completion(trigger) {
                        @Override
                        public void success() {
                          trigger.next();
                        }

                        @Override
                        public void fail(ErrorCode errorCode) {
                          trigger.fail(errorCode);
                        }
                      });
                }
              });
    } else {
      chain.then(
          new NoRollbackFlow() {
            @Override
            public void run(final FlowTrigger trigger, Map data) {
              casf.asyncCascade(
                  CascadeConstant.DELETION_FORCE_DELETE_CODE,
                  issuer,
                  ctx,
                  new Completion(trigger) {
                    @Override
                    public void success() {
                      trigger.next();
                    }

                    @Override
                    public void fail(ErrorCode errorCode) {
                      trigger.fail(errorCode);
                    }
                  });
            }
          });
    }

    chain
        .done(
            new FlowDoneHandler(msg) {
              @Override
              public void handle(Map data) {
                casf.asyncCascadeFull(
                    CascadeConstant.DELETION_CLEANUP_CODE, issuer, ctx, new NopeCompletion());
                bus.publish(evt);
              }
            })
        .error(
            new FlowErrorHandler(msg) {
              @Override
              public void handle(ErrorCode errCode, Map data) {
                evt.setErrorCode(
                    errf.instantiateErrorCode(SysErrors.DELETE_RESOURCE_ERROR, errCode));
                bus.publish(evt);
              }
            })
        .start();
  }
  private void applyEip(
      final VirtualRouterVmInventory vr, final EipStruct struct, final Completion completion) {
    FlowChain chain = FlowChainBuilder.newSimpleFlowChain();
    chain.setName(String.format("apply-eip-%s-vr-%s", struct.getEip().getUuid(), vr.getUuid()));
    chain
        .then(
            new Flow() {
              @Override
              public void run(final FlowTrigger trigger, Map data) {
                asf.openFirewall(
                    vr.getUuid(),
                    struct.getVip().getL3NetworkUuid(),
                    getFirewallRules(struct),
                    new Completion(trigger) {
                      @Override
                      public void success() {
                        trigger.next();
                      }

                      @Override
                      public void fail(ErrorCode errorCode) {
                        trigger.fail(errorCode);
                      }
                    });
              }

              @Override
              public void rollback(final FlowRollback trigger, Map data) {
                asf.removeFirewall(
                    vr.getUuid(),
                    struct.getVip().getL3NetworkUuid(),
                    getFirewallRules(struct),
                    new Completion(trigger) {
                      @Override
                      public void success() {
                        trigger.rollback();
                      }

                      @Override
                      public void fail(ErrorCode errorCode) {
                        logger.warn(
                            String.format(
                                "failed to remove firewall rules on virtual router[uuid:%s, l3Network uuid:%s], %s",
                                vr.getUuid(), struct.getVip().getL3NetworkUuid(), errorCode));
                        trigger.rollback();
                      }
                    });
              }
            })
        .then(
            new NoRollbackFlow() {
              @Override
              public void run(final FlowTrigger trigger, Map data) {
                EipTO to = new EipTO();
                String priMac =
                    CollectionUtils.find(
                        vr.getVmNics(),
                        new Function<String, VmNicInventory>() {
                          @Override
                          public String call(VmNicInventory arg) {
                            if (arg.getL3NetworkUuid().equals(struct.getNic().getL3NetworkUuid())) {
                              return arg.getMac();
                            }
                            return null;
                          }
                        });
                to.setPrivateMac(priMac);
                to.setVipIp(struct.getVip().getIp());
                to.setGuestIp(struct.getNic().getIp());
                to.setSnatInboundTraffic(struct.isSnatInboundTraffic());

                VirtualRouterCommands.CreateEipCmd cmd = new VirtualRouterCommands.CreateEipCmd();
                cmd.setEip(to);
                VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg();
                msg.setCheckStatus(true);
                msg.setPath(VirtualRouterConstant.VR_CREATE_EIP);
                msg.setCommand(cmd);
                msg.setVmInstanceUuid(vr.getUuid());
                bus.makeTargetServiceIdByResourceUuid(
                    msg, VmInstanceConstant.SERVICE_ID, vr.getUuid());
                bus.send(
                    msg,
                    new CloudBusCallBack(completion) {
                      @Override
                      public void run(MessageReply reply) {
                        if (!reply.isSuccess()) {
                          trigger.fail(reply.getError());
                          return;
                        }

                        VirtualRouterAsyncHttpCallReply re = reply.castReply();
                        CreateEipRsp ret = re.toResponse(CreateEipRsp.class);
                        if (ret.isSuccess()) {
                          trigger.next();
                        } else {
                          trigger.fail(
                              errf.stringToOperationError(
                                  String.format(
                                      "failed to create eip[uuid:%s, name:%s, ip:%s] for vm nic[uuid:%s] on virtual router[uuid:%s], %s",
                                      struct.getEip().getUuid(),
                                      struct.getEip().getName(),
                                      struct.getVip().getIp(),
                                      struct.getNic().getUuid(),
                                      vr.getUuid(),
                                      ret.getError())));
                        }
                      }
                    });
              }
            })
        .done(
            new FlowDoneHandler(completion) {
              @Override
              public void handle(Map data) {
                String info =
                    String.format(
                        "successfully created eip[uuid:%s, name:%s, ip:%s] for vm nic[uuid:%s] on virtual router[uuid:%s]",
                        struct.getEip().getUuid(),
                        struct.getEip().getName(),
                        struct.getVip().getIp(),
                        struct.getNic().getUuid(),
                        vr.getUuid());
                new VirtualRouterRoleManager().makeEipRole(vr.getUuid());
                logger.debug(info);
                completion.success();
              }
            })
        .error(
            new FlowErrorHandler(completion) {
              @Override
              public void handle(ErrorCode errCode, Map data) {
                completion.fail(errCode);
              }
            })
        .start();
  }
Beispiel #3
0
  private void handle(final ImageDeletionMsg msg) {
    final ImageDeletionReply reply = new ImageDeletionReply();
    if (self.getBackupStorageRefs().isEmpty()) {
      // the image is not on any backup storage; mostly likely the image is not in the status of
      // Ready, for example
      // it's still downloading
      // in this case, we directly delete it from the database
      dbf.remove(self);
      bus.reply(msg, reply);
      return;
    }

    final ImageDeletionPolicy deletionPolicy =
        msg.getDeletionPolicy() == null
            ? deletionPolicyMgr.getDeletionPolicy(self.getUuid())
            : ImageDeletionPolicy.valueOf(msg.getDeletionPolicy());
    FlowChain chain = FlowChainBuilder.newSimpleFlowChain();
    chain.setName(String.format("delete-image-%s", self.getUuid()));
    Collection<ImageBackupStorageRefVO> toDelete =
        msg.getBackupStorageUuids() == null
            ? self.getBackupStorageRefs()
            : CollectionUtils.transformToList(
                self.getBackupStorageRefs(),
                new Function<ImageBackupStorageRefVO, ImageBackupStorageRefVO>() {
                  @Override
                  public ImageBackupStorageRefVO call(ImageBackupStorageRefVO arg) {
                    return msg.getBackupStorageUuids().contains(arg.getBackupStorageUuid())
                        ? arg
                        : null;
                  }
                });

    for (final ImageBackupStorageRefVO ref : toDelete) {
      chain.then(
          new NoRollbackFlow() {
            String __name__ =
                String.format(
                    "delete-image-%s-from-backup-storage-%s",
                    self.getUuid(), ref.getBackupStorageUuid());

            @Override
            public void run(final FlowTrigger trigger, Map data) {
              if (deletionPolicy == ImageDeletionPolicy.Direct) {
                DeleteBitsOnBackupStorageMsg dmsg = new DeleteBitsOnBackupStorageMsg();
                dmsg.setBackupStorageUuid(ref.getBackupStorageUuid());
                dmsg.setInstallPath(ref.getInstallPath());
                bus.makeTargetServiceIdByResourceUuid(
                    dmsg, BackupStorageConstant.SERVICE_ID, dmsg.getBackupStorageUuid());
                bus.send(
                    dmsg,
                    new CloudBusCallBack(trigger) {
                      @Override
                      public void run(MessageReply reply) {
                        if (!reply.isSuccess()) {
                          // TODO
                          logger.warn(
                              String.format(
                                  "failed to delete image[uuid:%s, name:%s] from backup storage[uuid:%s] because %s, need to garbage collect it",
                                  self.getUuid(),
                                  self.getName(),
                                  reply.getError(),
                                  ref.getBackupStorageUuid()));
                        } else {
                          returnBackupStorageCapacity(ref.getBackupStorageUuid(), self.getSize());
                          dbf.remove(ref);
                        }
                        trigger.next();
                      }
                    });
              } else if (deletionPolicy == ImageDeletionPolicy.DeleteReference) {
                dbf.remove(ref);
                logger.debug(
                    String.format(
                        "delete the image[uuid: %s, name:%s]'s reference of the backup storage[uuid:%s]",
                        self.getUuid(), self.getName(), ref.getBackupStorageUuid()));
                trigger.next();
              } else {
                ref.setStatus(ImageStatus.Deleted);
                dbf.update(ref);
                trigger.next();
              }
            }
          });
    }

    chain
        .done(
            new FlowDoneHandler(msg) {
              @Override
              public void handle(Map data) {
                self = dbf.reload(self);
                if (self.getBackupStorageRefs().isEmpty()) {
                  dbf.remove(self);
                  if (deletionPolicy == ImageDeletionPolicy.DeleteReference) {
                    logger.debug(
                        String.format(
                            "successfully directly deleted the image[uuid:%s, name:%s] from the database,"
                                + " as the policy is DeleteReference, it's still on the physical backup storage",
                            self.getUuid(), self.getName()));
                  } else {
                    logger.debug(
                        String.format(
                            "successfully directly deleted the image[uuid:%s, name:%s]",
                            self.getUuid(), self.getName()));
                  }
                } else {
                  int deleteCount = 0;
                  for (ImageBackupStorageRefVO ref : self.getBackupStorageRefs()) {
                    if (ref.getStatus() == ImageStatus.Deleted) {
                      deleteCount++;
                    }
                  }
                  if (deleteCount == self.getBackupStorageRefs().size()) {
                    self.setStatus(ImageStatus.Deleted);
                    self = dbf.updateAndRefresh(self);
                    logger.debug(
                        String.format(
                            "successfully deleted the image[uuid:%s, name:%s] with deletion policy[%s]",
                            self.getUuid(), self.getName(), deletionPolicy));
                  }
                }

                bus.reply(msg, reply);
              }
            })
        .error(
            new FlowErrorHandler(msg) {
              @Override
              public void handle(ErrorCode errCode, Map data) {
                reply.setError(errCode);
                bus.reply(msg, reply);
              }
            })
        .start();
  }
  @Override
  public void revokeEip(final EipStruct struct, final Completion completion) {
    SimpleQuery<VirtualRouterEipRefVO> q = dbf.createQuery(VirtualRouterEipRefVO.class);
    q.add(VirtualRouterEipRefVO_.eipUuid, SimpleQuery.Op.EQ, struct.getEip().getUuid());
    final VirtualRouterEipRefVO ref = q.find();
    if (ref == null) {
      // vr may have been deleted
      completion.success();
      return;
    }

    VirtualRouterVmVO vrvo = dbf.findByUuid(ref.getVirtualRouterVmUuid(), VirtualRouterVmVO.class);
    if (vrvo.getState() != VmInstanceState.Running) {
      // rule will be synced when vr state changes to Running
      completion.success();
      return;
    }

    final VirtualRouterVmInventory vr = VirtualRouterVmInventory.valueOf(vrvo);

    // TODO: how to cleanup on failure
    final FlowChain chain = FlowChainBuilder.newSimpleFlowChain();
    chain.setName(String.format("revoke-eip-%s-vr-%s", struct.getEip().getUuid(), vr.getUuid()));
    chain
        .then(
            new NoRollbackFlow() {
              @Override
              public void run(final FlowTrigger trigger, Map data) {
                VirtualRouterCommands.RemoveEipCmd cmd = new VirtualRouterCommands.RemoveEipCmd();
                EipTO to = new EipTO();
                String priMac =
                    CollectionUtils.find(
                        vr.getVmNics(),
                        new Function<String, VmNicInventory>() {
                          @Override
                          public String call(VmNicInventory arg) {
                            if (arg.getL3NetworkUuid().equals(struct.getNic().getL3NetworkUuid())) {
                              return arg.getMac();
                            }
                            return null;
                          }
                        });

                to.setPrivateMac(priMac);
                to.setSnatInboundTraffic(struct.isSnatInboundTraffic());
                to.setVipIp(struct.getVip().getIp());
                to.setGuestIp(struct.getNic().getIp());
                cmd.setEip(to);

                VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg();
                msg.setVmInstanceUuid(vr.getUuid());
                msg.setCommand(cmd);
                msg.setCheckStatus(true);
                msg.setPath(VirtualRouterConstant.VR_REMOVE_EIP);
                bus.makeTargetServiceIdByResourceUuid(
                    msg, VmInstanceConstant.SERVICE_ID, vr.getUuid());
                bus.send(
                    msg,
                    new CloudBusCallBack(trigger) {
                      @Override
                      public void run(MessageReply reply) {
                        if (!reply.isSuccess()) {
                          trigger.setError(reply.getError());
                        } else {
                          VirtualRouterAsyncHttpCallReply re = reply.castReply();
                          RemoveEipRsp ret = re.toResponse(RemoveEipRsp.class);
                          if (!ret.isSuccess()) {
                            String err =
                                String.format(
                                    "failed to remove eip[uuid:%s, name:%s, ip:%s] for vm nic[uuid:%s] on virtual router[uuid:%s], %s",
                                    struct.getEip().getUuid(),
                                    struct.getEip().getName(),
                                    struct.getVip().getIp(),
                                    struct.getNic().getUuid(),
                                    vr.getUuid(),
                                    ret.getError());
                            trigger.setError(errf.stringToOperationError(err));
                          }
                        }

                        trigger.next();
                      }
                    });
              }
            })
        .then(
            new NoRollbackFlow() {
              @Override
              public void run(final FlowTrigger trigger, Map data) {
                asf.removeFirewall(
                    vr.getUuid(),
                    struct.getVip().getL3NetworkUuid(),
                    getFirewallRules(struct),
                    new Completion() {
                      @Override
                      public void success() {
                        trigger.next();
                      }

                      @Override
                      public void fail(ErrorCode errorCode) {
                        logger.warn(
                            String.format(
                                "failed to remove firewall rules on virtual router[uuid:%s, l3Network uuid:%s], %s",
                                vr.getUuid(), struct.getVip().getL3NetworkUuid(), errorCode));
                        trigger.next();
                      }
                    });
              }
            })
        .done(
            new FlowDoneHandler(completion) {
              @Override
              public void handle(Map data) {
                String info =
                    String.format(
                        "successfully removed eip[uuid:%s, name:%s, ip:%s] for vm nic[uuid:%s] on virtual router[uuid:%s]",
                        struct.getEip().getUuid(),
                        struct.getEip().getName(),
                        struct.getVip().getIp(),
                        struct.getNic().getUuid(),
                        vr.getUuid());
                logger.debug(info);
                dbf.remove(ref);
                completion.success();
              }
            })
        .error(
            new FlowErrorHandler(completion) {
              @Override
              public void handle(ErrorCode errCode, Map data) {
                completion.fail(errCode);
              }
            })
        .start();
  }