@Override public void handleSingleWorkingRedundantRouter( final List<? extends VirtualRouter> connectedRouters, final List<? extends VirtualRouter> disconnectedRouters, final String reason) throws ResourceUnavailableException { if (connectedRouters.isEmpty() || disconnectedRouters.isEmpty()) { return; } for (final VirtualRouter virtualRouter : connectedRouters) { if (!virtualRouter.getIsRedundantRouter()) { throw new ResourceUnavailableException( "Who is calling this with non-redundant router or non-domain router?", DataCenter.class, virtualRouter.getDataCenterId()); } } for (final VirtualRouter virtualRouter : disconnectedRouters) { if (!virtualRouter.getIsRedundantRouter()) { throw new ResourceUnavailableException( "Who is calling this with non-redundant router or non-domain router?", DataCenter.class, virtualRouter.getDataCenterId()); } } final DomainRouterVO connectedRouter = (DomainRouterVO) connectedRouters.get(0); DomainRouterVO disconnectedRouter = (DomainRouterVO) disconnectedRouters.get(0); if (s_logger.isDebugEnabled()) { s_logger.debug( "About to stop the router " + disconnectedRouter.getInstanceName() + " due to: " + reason); } final String title = "Virtual router " + disconnectedRouter.getInstanceName() + " would be stopped after connecting back, due to " + reason; final String context = "Virtual router (name: " + disconnectedRouter.getInstanceName() + ", id: " + disconnectedRouter.getId() + ") would be stopped after connecting back, due to: " + reason; _alertMgr.sendAlert( AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, disconnectedRouter.getDataCenterId(), disconnectedRouter.getPodIdToDeployIn(), title, context); disconnectedRouter.setStopPending(true); disconnectedRouter = _routerDao.persist(disconnectedRouter); }
private DomainRouterVO findELBVmWithCapacity(Network guestNetwork, IPAddressVO ipAddr) { List<DomainRouterVO> unusedElbVms = _elbVmMapDao.listUnusedElbVms(); if (unusedElbVms.size() > 0) { List<DomainRouterVO> candidateVms = new ArrayList<DomainRouterVO>(); for (DomainRouterVO candidateVm : unusedElbVms) { if (candidateVm.getPodIdToDeployIn() == getPodIdForDirectIp(ipAddr)) candidateVms.add(candidateVm); } return candidateVms.size() == 0 ? null : candidateVms.get(new Random().nextInt(candidateVms.size())); } return null; }
@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; }