Example #1
0
  @Override
  public DomainRouterVO startVirtualRouter(
      final DomainRouterVO router,
      final User user,
      final Account caller,
      final Map<Param, Object> params)
      throws StorageUnavailableException, InsufficientCapacityException,
          ConcurrentOperationException, ResourceUnavailableException {

    if (router.getRole() != Role.VIRTUAL_ROUTER || !router.getIsRedundantRouter()) {
      return start(router, user, caller, params, null);
    }

    if (router.getState() == State.Running) {
      s_logger.debug("Redundant router " + router.getInstanceName() + " is already running!");
      return router;
    }

    //
    // If another thread has already requested a VR start, there is a
    // transition period for VR to transit from
    // Starting to Running, there exist a race conditioning window here
    // We will wait until VR is up or fail
    if (router.getState() == State.Starting) {
      return waitRouter(router);
    }

    final DataCenterDeployment plan = new DataCenterDeployment(0, null, null, null, null, null);
    DomainRouterVO result = null;
    assert router.getIsRedundantRouter();
    final List<Long> networkIds = _routerDao.getRouterNetworks(router.getId());

    DomainRouterVO routerToBeAvoid = null;
    if (networkIds.size() != 0) {
      final List<DomainRouterVO> routerList = _routerDao.findByNetwork(networkIds.get(0));
      for (final DomainRouterVO rrouter : routerList) {
        if (rrouter.getHostId() != null
            && rrouter.getIsRedundantRouter()
            && rrouter.getState() == State.Running) {
          if (routerToBeAvoid != null) {
            throw new ResourceUnavailableException(
                "Try to start router "
                    + router.getInstanceName()
                    + "("
                    + router.getId()
                    + ")"
                    + ", but there are already two redundant routers with IP "
                    + router.getPublicIpAddress()
                    + ", they are "
                    + rrouter.getInstanceName()
                    + "("
                    + rrouter.getId()
                    + ") and "
                    + routerToBeAvoid.getInstanceName()
                    + "("
                    + routerToBeAvoid.getId()
                    + ")",
                DataCenter.class,
                rrouter.getDataCenterId());
          }
          routerToBeAvoid = rrouter;
        }
      }
    }
    if (routerToBeAvoid == null) {
      return start(router, user, caller, params, null);
    }
    // We would try best to deploy the router to another place
    final int retryIndex = 5;
    final ExcludeList[] avoids = new ExcludeList[5];
    avoids[0] = new ExcludeList();
    avoids[0].addPod(routerToBeAvoid.getPodIdToDeployIn());
    avoids[1] = new ExcludeList();
    avoids[1].addCluster(_hostDao.findById(routerToBeAvoid.getHostId()).getClusterId());
    avoids[2] = new ExcludeList();
    final List<VolumeVO> volumes =
        _volumeDao.findByInstanceAndType(routerToBeAvoid.getId(), Volume.Type.ROOT);
    if (volumes != null && volumes.size() != 0) {
      avoids[2].addPool(volumes.get(0).getPoolId());
    }
    avoids[2].addHost(routerToBeAvoid.getHostId());
    avoids[3] = new ExcludeList();
    avoids[3].addHost(routerToBeAvoid.getHostId());
    avoids[4] = new ExcludeList();

    for (int i = 0; i < retryIndex; i++) {
      if (s_logger.isTraceEnabled()) {
        s_logger.trace(
            "Try to deploy redundant virtual router:"
                + router.getHostName()
                + ", for "
                + i
                + " time");
      }
      plan.setAvoids(avoids[i]);
      try {
        result = start(router, user, caller, params, plan);
      } catch (final InsufficientServerCapacityException ex) {
        result = null;
      }
      if (result != null) {
        break;
      }
    }
    return result;
  }