http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/src/com/cloud/network/router/NetworkHelperImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/NetworkHelperImpl.java 
b/server/src/com/cloud/network/router/NetworkHelperImpl.java
new file mode 100644
index 0000000..bcebcd7
--- /dev/null
+++ b/server/src/com/cloud/network/router/NetworkHelperImpl.java
@@ -0,0 +1,820 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network.router;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import 
org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.log4j.Logger;
+import org.cloud.network.router.deployment.RouterDeploymentDefinition;
+import org.springframework.stereotype.Component;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.BumpUpPriorityCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.manager.Commands;
+import com.cloud.alert.AlertManager;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.Pod;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InsufficientServerCapacityException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.maint.Version;
+import com.cloud.network.IpAddressManager;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.VirtualNetworkApplianceService;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.UserIpv6AddressDao;
+import com.cloud.network.router.VirtualRouter.RedundantState;
+import com.cloud.network.router.VirtualRouter.Role;
+import com.cloud.network.vpn.Site2SiteVpnManager;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.resource.ResourceManager;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.Volume;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VolumeDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.User;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VirtualMachineName;
+import com.cloud.vm.VirtualMachineProfile.Param;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
+
+@Component
+//This will not be a public service anymore, but a helper for the only public 
service
+@Local(value = {NetworkHelperImpl.class})
+public class NetworkHelperImpl implements NetworkHelper {
+
+    private static final Logger s_logger = 
Logger.getLogger(NetworkHelperImpl.class);
+
+    @Inject
+    protected NicDao _nicDao;
+    @Inject
+    private NetworkDao _networkDao;
+    @Inject
+    protected DomainRouterDao _routerDao;
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    private AlertManager _alertMgr;
+    @Inject
+    protected NetworkModel _networkModel;
+    @Inject
+    private VirtualMachineManager _itMgr;
+    @Inject
+    private AccountManager _accountMgr;
+    @Inject
+    private Site2SiteVpnManager _s2sVpnMgr;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    private VolumeDao _volumeDao;
+    @Inject
+    private ServiceOfferingDao _serviceOfferingDao;
+    @Inject
+    private VMTemplateDao _templateDao;
+    @Inject
+    private ResourceManager _resourceMgr;
+    @Inject
+    private ClusterDao _clusterDao;
+    @Inject
+    protected IPAddressDao _ipAddressDao;
+    @Inject
+    private IpAddressManager _ipAddrMgr;
+    @Inject
+    private UserIpv6AddressDao _ipv6Dao;
+    @Inject
+    protected NetworkOrchestrationService _networkMgr;
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.router.NetworkHelper#getRouterControlIp(long)
+     */
+    @Override
+    public String getRouterControlIp(final long routerId) {
+        String routerControlIpAddress = null;
+        final List<NicVO> nics = _nicDao.listByVmId(routerId);
+        for (final NicVO n : nics) {
+            final NetworkVO nc = _networkDao.findById(n.getNetworkId());
+            if (nc != null && nc.getTrafficType() == TrafficType.Control) {
+                routerControlIpAddress = n.getIp4Address();
+                // router will have only one control ip
+                break;
+            }
+        }
+
+        if (routerControlIpAddress == null) {
+            s_logger.warn("Unable to find router's control ip in its attached 
NICs!. routerId: " + routerId);
+            final DomainRouterVO router = _routerDao.findById(routerId);
+            return router.getPrivateIpAddress();
+        }
+
+        return routerControlIpAddress;
+    }
+
+    /* (non-Javadoc)
+     * @see com.cloud.network.router.NetworkHelper#getRouterIpInNetwork(long, 
long)
+     */
+    @Override
+    public String getRouterIpInNetwork(final long networkId, final long 
instanceId) {
+        return _nicDao.getIpAddress(networkId, instanceId);
+    }
+
+
+    //    @Override
+    /* (non-Javadoc)
+     * @see 
com.cloud.network.router.NetworkHelper#sendCommandsToRouter(com.cloud.network.router.VirtualRouter,
 com.cloud.agent.manager.Commands)
+     */
+    @Override
+    public boolean sendCommandsToRouter(final VirtualRouter router, final 
Commands cmds) throws AgentUnavailableException {
+        if(!checkRouterVersion(router)){
+            s_logger.debug("Router requires upgrade. Unable to send command to 
router:" + router.getId() + ", router template version : " + 
router.getTemplateVersion()
+                    + ", minimal required version : " + 
VirtualNetworkApplianceService.MinVRVersion);
+            throw new CloudRuntimeException("Unable to send command. Upgrade 
in progress. Please contact administrator.");
+        }
+        Answer[] answers = null;
+        try {
+            answers = _agentMgr.send(router.getHostId(), cmds);
+        } catch (final OperationTimedoutException e) {
+            s_logger.warn("Timed Out", e);
+            throw new AgentUnavailableException("Unable to send commands to 
virtual router ", router.getHostId(), e);
+        }
+
+        if (answers == null) {
+            return false;
+        }
+
+        if (answers.length != cmds.size()) {
+            return false;
+        }
+
+        // FIXME: Have to return state for individual command in the future
+        boolean result = true;
+        if (answers.length > 0) {
+            for (final Answer answer : answers) {
+                if (!answer.getResult()) {
+                    result = false;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    @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;
+        }
+        if (connectedRouters.size() != 1 || disconnectedRouters.size() != 1) {
+            s_logger.warn("How many redundant routers do we have?? ");
+            return;
+        }
+        if (!connectedRouters.get(0).getIsRedundantRouter()) {
+            throw new ResourceUnavailableException("Who is calling this with 
non-redundant router or non-domain router?", DataCenter.class, 
connectedRouters.get(0)
+                    .getDataCenterId());
+        }
+        if (!disconnectedRouters.get(0).getIsRedundantRouter()) {
+            throw new ResourceUnavailableException("Who is calling this with 
non-redundant router or non-domain router?", DataCenter.class, 
disconnectedRouters.get(0)
+                    .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);
+
+        final int connRouterPR = getRealPriority(connectedRouter);
+        final int disconnRouterPR = getRealPriority(disconnectedRouter);
+        if (connRouterPR < disconnRouterPR) {
+            //connRouterPR < disconnRouterPR, they won't equal at anytime
+            if (!connectedRouter.getIsPriorityBumpUp()) {
+                final BumpUpPriorityCommand command = new 
BumpUpPriorityCommand();
+                command.setAccessDetail(NetworkElementCommand.ROUTER_IP, 
getRouterControlIp(connectedRouter.getId()));
+                command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, 
connectedRouter.getInstanceName());
+                final Answer answer = 
_agentMgr.easySend(connectedRouter.getHostId(), command);
+                if (!answer.getResult()) {
+                    s_logger.error("Failed to bump up " + 
connectedRouter.getInstanceName() + "'s priority! " + answer.getDetails());
+                }
+            } else {
+                final String t = "Can't bump up virtual router " + 
connectedRouter.getInstanceName() + "'s priority due to it's already bumped 
up!";
+                
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_DOMAIN_ROUTER, 
connectedRouter.getDataCenterId(), connectedRouter.getPodIdToDeployIn(), t, t);
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see 
com.cloud.network.router.NetworkHelper#getRealPriority(com.cloud.vm.DomainRouterVO)
+     */
+    @Override
+    public int getRealPriority(final DomainRouterVO router) {
+        int priority = router.getPriority();
+        if (router.getIsPriorityBumpUp()) {
+            priority += VirtualNetworkApplianceManager.DEFAULT_DELTA;
+        }
+        return priority;
+    }
+
+    //    @Override
+    /* (non-Javadoc)
+     * @see 
com.cloud.network.router.NetworkHelper#getNicTO(com.cloud.network.router.VirtualRouter,
 java.lang.Long, java.lang.String)
+     */
+    @Override
+    public NicTO getNicTO(final VirtualRouter router, final Long networkId, 
final String broadcastUri) {
+        NicProfile nicProfile = _networkModel.getNicProfile(router, networkId, 
broadcastUri);
+
+        return _itMgr.toNicTO(nicProfile, router.getHypervisorType());
+    }
+
+    //    @Override
+    /* (non-Javadoc)
+     * @see com.cloud.network.router.NetworkHelper#destroyRouter(long, 
com.cloud.user.Account, java.lang.Long)
+     */
+    @Override
+    public VirtualRouter destroyRouter(final long routerId, final Account 
caller, final Long callerUserId) throws ResourceUnavailableException, 
ConcurrentOperationException {
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Attempting to destroy router " + routerId);
+        }
+
+        final DomainRouterVO router = _routerDao.findById(routerId);
+        if (router == null) {
+            return null;
+        }
+
+        _accountMgr.checkAccess(caller, null, true, router);
+
+        _itMgr.expunge(router.getUuid());
+        _routerDao.remove(router.getId());
+        return router;
+    }
+
+    /* (non-Javadoc)
+     * @see 
com.cloud.network.router.NetworkHelper#checkRouterVersion(com.cloud.network.router.VirtualRouter)
+     */
+    //    @Override
+    @Override
+    public boolean checkRouterVersion(final VirtualRouter router) {
+        
if(!VirtualNetworkApplianceManagerImpl.routerVersionCheckEnabled.value()){
+            //Router version check is disabled.
+            return true;
+        }
+        if(router.getTemplateVersion() == null){
+            return false;
+        }
+        final String trimmedVersion = 
Version.trimRouterVersion(router.getTemplateVersion());
+        return Version.compare(trimmedVersion, 
VirtualNetworkApplianceService.MinVRVersion) >= 0;
+    }
+
+
+    protected DomainRouterVO start(DomainRouterVO router, final User user, 
final Account caller, final Map<Param, Object> params, final DeploymentPlan 
planToDeploy)
+            throws StorageUnavailableException, InsufficientCapacityException, 
ConcurrentOperationException, ResourceUnavailableException {
+        s_logger.debug("Starting router " + router);
+        try {
+            _itMgr.advanceStart(router.getUuid(), params, planToDeploy, null);
+        } catch (final OperationTimedoutException e) {
+            throw new ResourceUnavailableException("Starting router " + router 
+ " failed! " + e.toString(), DataCenter.class, router.getDataCenterId());
+        }
+        if (router.isStopPending()) {
+            s_logger.info("Clear the stop pending flag of router " + 
router.getHostName() + " after start router successfully!");
+            router.setStopPending(false);
+            router = _routerDao.persist(router);
+        }
+        // We don't want the failure of VPN Connection affect the status of 
router, so we try to make connection
+        // only after router start successfully
+        final Long vpcId = router.getVpcId();
+        if (vpcId != null) {
+            _s2sVpnMgr.reconnectDisconnectedVpnByVpc(vpcId);
+        }
+        return _routerDao.findById(router.getId());
+    }
+
+    protected DomainRouterVO waitRouter(final DomainRouterVO router) {
+        DomainRouterVO vm = _routerDao.findById(router.getId());
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Router " + router.getInstanceName() + " is not 
fully up yet, we will wait");
+        }
+        while (vm.getState() == State.Starting) {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+
+            // reload to get the latest state info
+            vm = _routerDao.findById(router.getId());
+        }
+
+        if (vm.getState() == State.Running) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Router " + router.getInstanceName() + " is now 
fully up");
+            }
+
+            return router;
+        }
+
+        s_logger.warn("Router " + router.getInstanceName() + " failed to 
start. current state: " + vm.getState());
+        return null;
+    }
+
+
+    //    @Override
+    /* (non-Javadoc)
+     * @see 
com.cloud.network.router.NetworkHelper#startRouters(org.cloud.network.router.deployment.RouterDeploymentDefinition)
+     */
+    @Override
+    public List<DomainRouterVO> startRouters(final RouterDeploymentDefinition 
routerDeploymentDefinition)
+            throws StorageUnavailableException, InsufficientCapacityException,
+            ConcurrentOperationException, ResourceUnavailableException {
+
+        List<DomainRouterVO> runningRouters = new ArrayList<DomainRouterVO>();
+
+        for (DomainRouterVO router : routerDeploymentDefinition.getRouters()) {
+            boolean skip = false;
+            final State state = router.getState();
+            if (router.getHostId() != null && state != State.Running) {
+                final HostVO host = _hostDao.findById(router.getHostId());
+                if (host == null || host.getState() != Status.Up) {
+                    skip = true;
+                }
+            }
+            if (!skip) {
+                if (state != State.Running) {
+                    router = startVirtualRouter(router, 
_accountMgr.getSystemUser(), _accountMgr.getSystemAccount(),
+                            routerDeploymentDefinition.getParams());
+                }
+                if (router != null) {
+                    runningRouters.add(router);
+                }
+            }
+        }
+        return runningRouters;
+    }
+
+    //    @Override
+    /* (non-Javadoc)
+     * @see 
com.cloud.network.router.NetworkHelper#startVirtualRouter(com.cloud.vm.DomainRouterVO,
 com.cloud.user.User, com.cloud.user.Account, java.util.Map)
+     */
+    @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);
+        }
+
+        DataCenterDeployment plan = new DataCenterDeployment(0, null, null, 
null, null, null);
+        DomainRouterVO result = null;
+        assert router.getIsRedundantRouter();
+        final List<Long> networkIds = 
_routerDao.getRouterNetworks(router.getId());
+        //Not support VPC now
+        if (networkIds.size() > 1) {
+            throw new ResourceUnavailableException("Unable to support more 
than one guest network for redundant router now!", DataCenter.class, 
router.getDataCenterId());
+        }
+        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;
+    }
+
+    //    @Override
+//    public DomainRouterVO deployRouter(final RouterDeploymentDefinition 
routerDeploymentDefinition) {
+//        routerDeploymentDefinition.createNetwork();
+//        doDeployRouter
+//    }
+
+    //    @Override
+    /* (non-Javadoc)
+     * @see 
com.cloud.network.router.NetworkHelper#deployRouter(org.cloud.network.router.deployment.RouterDeploymentDefinition,
 java.util.LinkedHashMap, boolean, java.util.List)
+     */
+    @Override
+    public DomainRouterVO deployRouter(final RouterDeploymentDefinition 
routerDeploymentDefinition,
+            final LinkedHashMap<Network, List<? extends NicProfile>> networks,
+            final boolean startRouter, final List<HypervisorType> 
supportedHypervisors)
+                    throws InsufficientAddressCapacityException,
+                    InsufficientServerCapacityException, 
InsufficientCapacityException,
+                    StorageUnavailableException, ResourceUnavailableException {
+
+        final ServiceOfferingVO routerOffering = 
_serviceOfferingDao.findById(routerDeploymentDefinition.getOfferingId());
+        final DeployDestination dest = routerDeploymentDefinition.getDest();
+        final Account owner = routerDeploymentDefinition.getOwner();
+
+        // Router is the network element, we don't know the hypervisor type 
yet.
+        // Try to allocate the domR twice using diff hypervisors, and when 
failed both times, throw the exception up
+        final List<HypervisorType> hypervisors = 
getHypervisors(routerDeploymentDefinition, supportedHypervisors);
+
+        int allocateRetry = 0;
+        int startRetry = 0;
+        DomainRouterVO router = null;
+        for (final Iterator<HypervisorType> iter = hypervisors.iterator(); 
iter.hasNext();) {
+            final HypervisorType hType = iter.next();
+            try {
+                final long id = _routerDao.getNextInSequence(Long.class, "id");
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Allocating the VR i=" + id + " in 
datacenter " + dest.getDataCenter() + "with the hypervisor type " + hType);
+                }
+
+                String templateName = null;
+                switch (hType) {
+                    case XenServer:
+                        templateName = 
VirtualNetworkApplianceManager.RouterTemplateXen.valueIn(dest.getDataCenter().getId());
+                        break;
+                    case KVM:
+                        templateName = 
VirtualNetworkApplianceManager.RouterTemplateKvm.valueIn(dest.getDataCenter().getId());
+                        break;
+                    case VMware:
+                        templateName = 
VirtualNetworkApplianceManager.RouterTemplateVmware.valueIn(dest.getDataCenter().getId());
+                        break;
+                    case Hyperv:
+                        templateName = 
VirtualNetworkApplianceManager.RouterTemplateHyperV.valueIn(dest.getDataCenter().getId());
+                        break;
+                    case LXC:
+                        templateName = 
VirtualNetworkApplianceManager.RouterTemplateLxc.valueIn(dest.getDataCenter().getId());
+                        break;
+                    default:
+                        break;
+                }
+                final VMTemplateVO template = 
_templateDao.findRoutingTemplate(hType, templateName);
+
+                if (template == null) {
+                    s_logger.debug(hType + " won't support system vm, skip 
it");
+                    continue;
+                }
+
+                boolean offerHA = routerOffering.getOfferHA();
+                /* We don't provide HA to redundant router VMs, admin should 
own it all, and redundant router themselves are HA */
+                if (routerDeploymentDefinition.isRedundant()) {
+                    offerHA = false;
+                }
+
+                // routerDeploymentDefinition.getVpc().getId() ==> do not use 
VPC because it is not a VPC offering.
+                Long vpcId = routerDeploymentDefinition.getVpc() != null ? 
routerDeploymentDefinition.getVpc().getId() : null;
+
+                router = new DomainRouterVO(id, routerOffering.getId(), 
routerDeploymentDefinition.getVirtualProvider().getId(),
+                        VirtualMachineName.getRouterName(id, 
VirtualNwStatus.instance), template.getId(), template.getHypervisorType(),
+                        template.getGuestOSId(), owner.getDomainId(), 
owner.getId(), routerDeploymentDefinition.isRedundant(), 0,
+                        false, RedundantState.UNKNOWN, offerHA, false, vpcId);
+
+                
router.setDynamicallyScalable(template.isDynamicallyScalable());
+                router.setRole(Role.VIRTUAL_ROUTER);
+                router = _routerDao.persist(router);
+                _itMgr.allocate(router.getInstanceName(), template, 
routerOffering, networks, routerDeploymentDefinition.getPlan(), null);
+                router = _routerDao.findById(router.getId());
+            } catch (final InsufficientCapacityException ex) {
+                if (allocateRetry < 2 && iter.hasNext()) {
+                    s_logger.debug("Failed to allocate the VR with hypervisor 
type " + hType + ", retrying one more time");
+                    continue;
+                } else {
+                    throw ex;
+                }
+            } finally {
+                allocateRetry++;
+            }
+
+            if (startRouter) {
+                try {
+                    router = startVirtualRouter(router, 
_accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), 
routerDeploymentDefinition.getParams());
+                    break;
+                } catch (final InsufficientCapacityException ex) {
+                    if (startRetry < 2 && iter.hasNext()) {
+                        s_logger.debug("Failed to start the VR  " + router + " 
with hypervisor type " + hType + ", " + "destroying it and recreating one more 
time");
+                        // destroy the router
+                        destroyRouter(router.getId(), 
_accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM);
+                        continue;
+                    } else {
+                        throw ex;
+                    }
+                } finally {
+                    startRetry++;
+                }
+            } else {
+                //return stopped router
+                return router;
+            }
+        }
+
+        return router;
+    }
+
+    protected List<HypervisorType> getHypervisors(final 
RouterDeploymentDefinition routerDeploymentDefinition, final 
List<HypervisorType> supportedHypervisors)
+            throws InsufficientServerCapacityException {
+        final DeployDestination dest = routerDeploymentDefinition.getDest();
+        List<HypervisorType> hypervisors = new ArrayList<HypervisorType>();
+
+        if (dest.getCluster() != null) {
+            if (dest.getCluster().getHypervisorType() == HypervisorType.Ovm) {
+                
hypervisors.add(getClusterToStartDomainRouterForOvm(dest.getCluster().getPodId()));
+            } else {
+                hypervisors.add(dest.getCluster().getHypervisorType());
+            }
+        } else {
+            final HypervisorType defaults = 
_resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId());
+            if (defaults != HypervisorType.None) {
+                hypervisors.add(defaults);
+            } else {
+                //if there is no default hypervisor, get it from the cluster
+                hypervisors = 
_resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, 
routerDeploymentDefinition.getPlan().getPodId());
+            }
+        }
+
+        //keep only elements defined in supported hypervisors
+        final StringBuilder hTypesStr = new StringBuilder();
+        if (supportedHypervisors != null && !supportedHypervisors.isEmpty()) {
+            hypervisors.retainAll(supportedHypervisors);
+            for (final HypervisorType hType : supportedHypervisors) {
+                hTypesStr.append(hType).append(" ");
+            }
+        }
+
+        if (hypervisors.isEmpty()) {
+            final String errMsg = hTypesStr.capacity() > 0 ? "supporting 
hypervisors " + hTypesStr.toString() : "";
+            if (routerDeploymentDefinition.getPodId() != null) {
+                throw new InsufficientServerCapacityException("Unable to 
create virtual router, " + "there are no clusters in the pod " + errMsg, 
Pod.class,
+                        routerDeploymentDefinition.getPodId());
+            }
+            throw new InsufficientServerCapacityException("Unable to create 
virtual router, " + "there are no clusters in the zone " + errMsg, 
DataCenter.class,
+                    dest.getDataCenter().getId());
+        }
+        return hypervisors;
+    }
+
+    /*
+     * Ovm won't support any system. So we have to choose a partner cluster in 
the same pod to start domain router for us
+     */
+    protected HypervisorType getClusterToStartDomainRouterForOvm(final long 
podId) {
+        final List<ClusterVO> clusters = _clusterDao.listByPodId(podId);
+        for (final ClusterVO cv : clusters) {
+            if (cv.getHypervisorType() == HypervisorType.Ovm || 
cv.getHypervisorType() == HypervisorType.BareMetal) {
+                continue;
+            }
+
+            final List<HostVO> hosts = 
_resourceMgr.listAllHostsInCluster(cv.getId());
+            if (hosts == null || hosts.isEmpty()) {
+                continue;
+            }
+
+            for (final HostVO h : hosts) {
+                if (h.getState() == Status.Up) {
+                    s_logger.debug("Pick up host that has hypervisor type " + 
h.getHypervisorType() + " in cluster " + cv.getId() + " to start domain router 
for OVM");
+                    return h.getHypervisorType();
+                }
+            }
+        }
+
+        final String errMsg =
+                new StringBuilder("Cannot find an available cluster in Pod ")
+        .append(podId)
+        .append(" to start domain router for Ovm. \n Ovm won't support any 
system vm including domain router, ")
+        .append("please make sure you have a cluster with hypervisor type of 
any of xenserver/KVM/Vmware in the same pod")
+        .append(" with Ovm cluster. And there is at least one host in UP 
status in that cluster.")
+        .toString();
+        throw new CloudRuntimeException(errMsg);
+    }
+
+
+    /* (non-Javadoc)
+     * @see 
com.cloud.network.router.NetworkHelper#createRouterNetworks(org.cloud.network.router.deployment.RouterDeploymentDefinition)
+     */
+    @Override
+    public LinkedHashMap<Network, List<? extends NicProfile>> 
createRouterNetworks(
+            final RouterDeploymentDefinition routerDeploymentDefinition)
+                    throws ConcurrentOperationException, 
InsufficientAddressCapacityException {
+
+        //Form networks
+        LinkedHashMap<Network, List<? extends NicProfile>> networks = new 
LinkedHashMap<Network, List<? extends NicProfile>>(3);
+        //1) Guest network
+        boolean hasGuestNetwork = false;
+        if (routerDeploymentDefinition.getGuestNetwork() != null) {
+            s_logger.debug("Adding nic for Virtual Router in Guest network " + 
routerDeploymentDefinition.getGuestNetwork());
+            String defaultNetworkStartIp = null, defaultNetworkStartIpv6 = 
null;
+            if (!routerDeploymentDefinition.isPublicNetwork()) {
+                final Nic placeholder = 
_networkModel.getPlaceholderNicForRouter(routerDeploymentDefinition.getGuestNetwork(),
 routerDeploymentDefinition.getPodId());
+                if (routerDeploymentDefinition.getGuestNetwork().getCidr() != 
null) {
+                    if (placeholder != null && placeholder.getIp4Address() != 
null) {
+                        s_logger.debug("Requesting ipv4 address " + 
placeholder.getIp4Address() + " stored in placeholder nic for the network " + 
routerDeploymentDefinition.getGuestNetwork());
+                        defaultNetworkStartIp = placeholder.getIp4Address();
+                    } else {
+                        final String startIp = 
_networkModel.getStartIpAddress(routerDeploymentDefinition.getGuestNetwork().getId());
+                        if (startIp != null && 
_ipAddressDao.findByIpAndSourceNetworkId(routerDeploymentDefinition.getGuestNetwork().getId(),
 startIp).getAllocatedTime() == null) {
+                            defaultNetworkStartIp = startIp;
+                        } else if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("First ipv4 " + startIp + " in 
network id=" + routerDeploymentDefinition.getGuestNetwork().getId() +
+                                    " is already allocated, can't use it for 
domain router; will get random ip address from the range");
+                        }
+                    }
+                }
+
+                if (routerDeploymentDefinition.getGuestNetwork().getIp6Cidr() 
!= null) {
+                    if (placeholder != null && placeholder.getIp6Address() != 
null) {
+                        s_logger.debug("Requesting ipv6 address " + 
placeholder.getIp6Address() + " stored in placeholder nic for the network " + 
routerDeploymentDefinition.getGuestNetwork());
+                        defaultNetworkStartIpv6 = placeholder.getIp6Address();
+                    } else {
+                        final String startIpv6 = 
_networkModel.getStartIpv6Address(routerDeploymentDefinition.getGuestNetwork().getId());
+                        if (startIpv6 != null && 
_ipv6Dao.findByNetworkIdAndIp(routerDeploymentDefinition.getGuestNetwork().getId(),
 startIpv6) == null) {
+                            defaultNetworkStartIpv6 = startIpv6;
+                        } else if (s_logger.isDebugEnabled()) {
+                            s_logger.debug("First ipv6 " + startIpv6 + " in 
network id=" + routerDeploymentDefinition.getGuestNetwork().getId() +
+                                    " is already allocated, can't use it for 
domain router; will get random ipv6 address from the range");
+                        }
+                    }
+                }
+            }
+
+            final NicProfile gatewayNic = new 
NicProfile(defaultNetworkStartIp, defaultNetworkStartIpv6);
+            if (routerDeploymentDefinition.isPublicNetwork()) {
+                if (routerDeploymentDefinition.isRedundant()) {
+                    
gatewayNic.setIp4Address(_ipAddrMgr.acquireGuestIpAddress(routerDeploymentDefinition.getGuestNetwork(),
 null));
+                } else {
+                    
gatewayNic.setIp4Address(routerDeploymentDefinition.getGuestNetwork().getGateway());
+                }
+                
gatewayNic.setBroadcastUri(routerDeploymentDefinition.getGuestNetwork().getBroadcastUri());
+                
gatewayNic.setBroadcastType(routerDeploymentDefinition.getGuestNetwork().getBroadcastDomainType());
+                
gatewayNic.setIsolationUri(routerDeploymentDefinition.getGuestNetwork().getBroadcastUri());
+                
gatewayNic.setMode(routerDeploymentDefinition.getGuestNetwork().getMode());
+                final String gatewayCidr = 
routerDeploymentDefinition.getGuestNetwork().getCidr();
+                gatewayNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr));
+            } else {
+                gatewayNic.setDefaultNic(true);
+            }
+
+            networks.put(routerDeploymentDefinition.getGuestNetwork(), new 
ArrayList<NicProfile>(Arrays.asList(gatewayNic)));
+            hasGuestNetwork = true;
+        }
+
+        //2) Control network
+        s_logger.debug("Adding nic for Virtual Router in Control network ");
+        List<? extends NetworkOffering> offerings = 
_networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork);
+        NetworkOffering controlOffering = offerings.get(0);
+        Network controlConfig = 
_networkMgr.setupNetwork(VirtualNwStatus.account, controlOffering, 
routerDeploymentDefinition.getPlan(),
+                null, null, false).get(0);
+        networks.put(controlConfig, new ArrayList<NicProfile>());
+        //3) Public network
+        if (routerDeploymentDefinition.isPublicNetwork()) {
+            s_logger.debug("Adding nic for Virtual Router in Public network ");
+            //if source nat service is supported by the network, get the 
source nat ip address
+            final NicProfile defaultNic = new NicProfile();
+            defaultNic.setDefaultNic(true);
+            final PublicIp sourceNatIp = 
routerDeploymentDefinition.getSourceNatIP();
+            defaultNic.setIp4Address(sourceNatIp.getAddress().addr());
+            defaultNic.setGateway(sourceNatIp.getGateway());
+            defaultNic.setNetmask(sourceNatIp.getNetmask());
+            defaultNic.setMacAddress(sourceNatIp.getMacAddress());
+            // get broadcast from public network
+            final Network pubNet = 
_networkDao.findById(sourceNatIp.getNetworkId());
+            if (pubNet.getBroadcastDomainType() == BroadcastDomainType.Vxlan) {
+                defaultNic.setBroadcastType(BroadcastDomainType.Vxlan);
+                
defaultNic.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag()));
+                
defaultNic.setIsolationUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag()));
+            } else {
+                defaultNic.setBroadcastType(BroadcastDomainType.Vlan);
+                
defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag()));
+                
defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag()));
+            }
+            if (hasGuestNetwork) {
+                defaultNic.setDeviceId(2);
+            }
+            final NetworkOffering publicOffering = 
_networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemPublicNetwork).get(0);
+            final List<? extends Network> publicNetworks = 
_networkMgr.setupNetwork(VirtualNwStatus.account, publicOffering,
+                    routerDeploymentDefinition.getPlan(), null, null, false);
+            final String publicIp = defaultNic.getIp4Address();
+            // We want to use the identical MAC address for RvR on public 
interface if possible
+            final NicVO peerNic = 
_nicDao.findByIp4AddressAndNetworkId(publicIp, publicNetworks.get(0).getId());
+            if (peerNic != null) {
+                s_logger.info("Use same MAC as previous RvR, the MAC is " + 
peerNic.getMacAddress());
+                defaultNic.setMacAddress(peerNic.getMacAddress());
+            }
+            networks.put(publicNetworks.get(0), new 
ArrayList<NicProfile>(Arrays.asList(defaultNic)));
+        }
+
+        return networks;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git 
a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java 
b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 4bf9e40..a798ef5 100644
--- 
a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ 
b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -385,7 +385,7 @@ public class VirtualNetworkApplianceManagerImpl extends 
ManagerBase implements V
     @Inject
     protected NetworkTopologyContext _networkTopologyContext;
     @Inject
-    protected NetworkGeneralHelper _nwHelper;
+    protected NetworkHelper _nwHelper;
     @Inject
     protected RouterDeploymentDefinitionBuilder 
_routerDeploymentManagerBuilder;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/src/com/cloud/network/router/VpcNetworkHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VpcNetworkHelper.java 
b/server/src/com/cloud/network/router/VpcNetworkHelper.java
new file mode 100644
index 0000000..fb26883
--- /dev/null
+++ b/server/src/com/cloud/network/router/VpcNetworkHelper.java
@@ -0,0 +1,15 @@
+package com.cloud.network.router;
+
+import com.cloud.network.Network;
+import com.cloud.network.vpc.VpcGateway;
+import com.cloud.vm.NicProfile;
+
+public interface VpcNetworkHelper extends NetworkHelper {
+
+    public abstract NicProfile createPrivateNicProfileForGateway(
+            VpcGateway privateGateway);
+
+    public abstract NicProfile createGuestNicProfileForVpcRouter(
+            Network guestNetwork);
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/src/com/cloud/network/router/VpcNetworkHelperImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VpcNetworkHelperImpl.java 
b/server/src/com/cloud/network/router/VpcNetworkHelperImpl.java
new file mode 100644
index 0000000..2e5d696
--- /dev/null
+++ b/server/src/com/cloud/network/router/VpcNetworkHelperImpl.java
@@ -0,0 +1,210 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network.router;
+
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.TreeSet;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import org.cloud.network.router.deployment.RouterDeploymentDefinition;
+import org.springframework.stereotype.Component;
+
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.network.IpAddress;
+import com.cloud.network.Network;
+import com.cloud.network.Networks.AddressFormat;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.IsolationType;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.vpc.PrivateGateway;
+import com.cloud.network.vpc.PrivateIpAddress;
+import com.cloud.network.vpc.PrivateIpVO;
+import com.cloud.network.vpc.VpcGateway;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.vpc.dao.PrivateIpDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.VMInstanceDao;
+
+
+@Component
+// This will not be a public service anymore, but a helper for the only public 
service
+@Local(value = {VpcNetworkHelperImpl.class})
+public class VpcNetworkHelperImpl extends NetworkHelperImpl implements 
VpcNetworkHelper {
+
+    private static final Logger s_logger = 
Logger.getLogger(VpcNetworkHelperImpl.class);
+
+    @Inject
+    private VMInstanceDao _vmDao;
+    @Inject
+    private PrivateIpDao _privateIpDao;
+    @Inject
+    private VlanDao _vlanDao;
+    @Inject
+    protected VpcManager _vpcMgr;
+
+
+    @Override
+    @DB
+    public NicProfile createPrivateNicProfileForGateway(VpcGateway 
privateGateway) {
+        Network privateNetwork = 
_networkModel.getNetwork(privateGateway.getNetworkId());
+        PrivateIpVO ipVO = 
_privateIpDao.allocateIpAddress(privateNetwork.getDataCenterId(), 
privateNetwork.getId(), privateGateway.getIp4Address());
+        Nic privateNic = 
_nicDao.findByIp4AddressAndNetworkId(ipVO.getIpAddress(), 
privateNetwork.getId());
+
+        NicProfile privateNicProfile = new NicProfile();
+
+        if (privateNic != null) {
+            VirtualMachine vm = _vmDao.findById(privateNic.getInstanceId());
+            privateNicProfile =
+                new NicProfile(privateNic, privateNetwork, 
privateNic.getBroadcastUri(), privateNic.getIsolationUri(), 
_networkModel.getNetworkRate(
+                    privateNetwork.getId(), vm.getId()), 
_networkModel.isSecurityGroupSupportedInNetwork(privateNetwork), 
_networkModel.getNetworkTag(
+                    vm.getHypervisorType(), privateNetwork));
+        } else {
+            String netmask = NetUtils.getCidrNetmask(privateNetwork.getCidr());
+            PrivateIpAddress ip =
+                new PrivateIpAddress(ipVO, 
privateNetwork.getBroadcastUri().toString(), privateNetwork.getGateway(), 
netmask,
+                    
NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(ipVO.getMacAddress())));
+
+            URI netUri = BroadcastDomainType.fromString(ip.getBroadcastUri());
+            privateNicProfile.setIp4Address(ip.getIpAddress());
+            privateNicProfile.setGateway(ip.getGateway());
+            privateNicProfile.setNetmask(ip.getNetmask());
+            privateNicProfile.setIsolationUri(netUri);
+            privateNicProfile.setBroadcastUri(netUri);
+            // can we solve this in setBroadcastUri()???
+            // or more plugable construct is desirable
+            
privateNicProfile.setBroadcastType(BroadcastDomainType.getSchemeValue(netUri));
+            privateNicProfile.setFormat(AddressFormat.Ip4);
+            
privateNicProfile.setReservationId(String.valueOf(ip.getBroadcastUri()));
+            privateNicProfile.setMacAddress(ip.getMacAddress());
+        }
+
+        return privateNicProfile;
+    }
+
+    /* (non-Javadoc)
+     * @see 
com.cloud.network.router.VpcNetworkHelper#createGuestNicProfileForVpcRouter(com.cloud.network.Network)
+     */
+    @Override
+    public NicProfile createGuestNicProfileForVpcRouter(final Network 
guestNetwork) {
+        NicProfile guestNic = new NicProfile();
+        guestNic.setIp4Address(guestNetwork.getGateway());
+        guestNic.setBroadcastUri(guestNetwork.getBroadcastUri());
+        guestNic.setBroadcastType(guestNetwork.getBroadcastDomainType());
+        guestNic.setIsolationUri(guestNetwork.getBroadcastUri());
+        guestNic.setMode(guestNetwork.getMode());
+        String gatewayCidr = guestNetwork.getCidr();
+        guestNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr));
+
+        return guestNic;
+    }
+
+    /* (non-Javadoc)
+     * @see 
com.cloud.network.router.VpcNetworkHelper#createVpcRouterNetworks(org.cloud.network.router.deployment.VpcRouterDeploymentDefinition)
+     */
+    @Override
+    public LinkedHashMap<Network, List<? extends NicProfile>> 
createRouterNetworks(
+            final RouterDeploymentDefinition vpcRouterDeploymentDefinition)
+                    throws ConcurrentOperationException, 
InsufficientAddressCapacityException {
+
+        final TreeSet<String> publicVlans = new TreeSet<String>();
+        
publicVlans.add(vpcRouterDeploymentDefinition.getSourceNatIP().getVlanTag());
+
+        //1) allocate nic for control and source nat public ip
+        final LinkedHashMap<Network, List<? extends NicProfile>> networks =
+                super.createRouterNetworks(vpcRouterDeploymentDefinition);
+
+
+        final Long vpcId = vpcRouterDeploymentDefinition.getVpc().getId();
+        //2) allocate nic for private gateways if needed
+        final List<PrivateGateway> privateGateways = 
this._vpcMgr.getVpcPrivateGateways(vpcId);
+        if (privateGateways != null && !privateGateways.isEmpty()) {
+            for (PrivateGateway privateGateway : privateGateways) {
+                NicProfile privateNic = 
this.createPrivateNicProfileForGateway(privateGateway);
+                Network privateNetwork = 
_networkModel.getNetwork(privateGateway.getNetworkId());
+                networks.put(privateNetwork, new 
ArrayList<NicProfile>(Arrays.asList(privateNic)));
+            }
+        }
+
+        //3) allocate nic for guest gateway if needed
+        List<? extends Network> guestNetworks = 
this._vpcMgr.getVpcNetworks(vpcId);
+        for (Network guestNetwork : guestNetworks) {
+            if (_networkModel.isPrivateGateway(guestNetwork.getId())) {
+                continue;
+            }
+            if (guestNetwork.getState() == Network.State.Implemented || 
guestNetwork.getState() == Network.State.Setup) {
+                NicProfile guestNic = 
createGuestNicProfileForVpcRouter(guestNetwork);
+                networks.put(guestNetwork, new 
ArrayList<NicProfile>(Arrays.asList(guestNic)));
+            }
+        }
+
+        //4) allocate nic for additional public network(s)
+        final List<IPAddressVO> ips = _ipAddressDao.listByAssociatedVpc(vpcId, 
false);
+        final List<NicProfile> publicNics = new ArrayList<NicProfile>();
+        Network publicNetwork = null;
+        for (IPAddressVO ip : ips) {
+            PublicIp publicIp = PublicIp.createFromAddrAndVlan(ip, 
this._vlanDao.findById(ip.getVlanId()));
+            if ((ip.getState() == IpAddress.State.Allocated || ip.getState() 
== IpAddress.State.Allocating) && this._vpcMgr.isIpAllocatedToVpc(ip) &&
+                    !publicVlans.contains(publicIp.getVlanTag())) {
+                s_logger.debug("Allocating nic for router in vlan " + 
publicIp.getVlanTag());
+                NicProfile publicNic = new NicProfile();
+                publicNic.setDefaultNic(false);
+                publicNic.setIp4Address(publicIp.getAddress().addr());
+                publicNic.setGateway(publicIp.getGateway());
+                publicNic.setNetmask(publicIp.getNetmask());
+                publicNic.setMacAddress(publicIp.getMacAddress());
+                publicNic.setBroadcastType(BroadcastDomainType.Vlan);
+                
publicNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(publicIp.getVlanTag()));
+                
publicNic.setIsolationUri(IsolationType.Vlan.toUri(publicIp.getVlanTag()));
+                NetworkOffering publicOffering = 
_networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemPublicNetwork).get(0);
+                if (publicNetwork == null) {
+                    List<? extends Network> publicNetworks = 
_networkMgr.setupNetwork(VirtualNwStatus.account,
+                            publicOffering, 
vpcRouterDeploymentDefinition.getPlan(), null, null, false);
+                    publicNetwork = publicNetworks.get(0);
+                }
+                publicNics.add(publicNic);
+                publicVlans.add(publicIp.getVlanTag());
+            }
+        }
+        if (publicNetwork != null) {
+            if (networks.get(publicNetwork) != null) {
+                List<NicProfile> publicNicProfiles = 
(List<NicProfile>)networks.get(publicNetwork);
+                publicNicProfiles.addAll(publicNics);
+                networks.put(publicNetwork, publicNicProfiles);
+            } else {
+                networks.put(publicNetwork, publicNics);
+            }
+        }
+
+        return networks;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git 
a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
 
b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
index 91461de..9af35d6 100644
--- 
a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
+++ 
b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
@@ -135,7 +135,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends 
VirtualNetworkApplian
     private EntityManager _entityMgr;
 
     @Inject
-    private VpcVirtualNetworkHelperImpl vpcHelper;
+    private VpcNetworkHelper vpcHelper;
 
     @Override
     public boolean configure(final String name, final Map<String, Object> 
params) throws ConfigurationException {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/src/com/cloud/network/router/VpcVirtualNetworkHelperImpl.java
----------------------------------------------------------------------
diff --git 
a/server/src/com/cloud/network/router/VpcVirtualNetworkHelperImpl.java 
b/server/src/com/cloud/network/router/VpcVirtualNetworkHelperImpl.java
deleted file mode 100644
index 373ee9f..0000000
--- a/server/src/com/cloud/network/router/VpcVirtualNetworkHelperImpl.java
+++ /dev/null
@@ -1,121 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.network.router;
-
-
-import java.net.URI;
-import java.util.List;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-
-import org.springframework.stereotype.Component;
-
-import com.cloud.network.Network;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks.AddressFormat;
-import com.cloud.network.Networks.BroadcastDomainType;
-import com.cloud.network.vpc.PrivateIpAddress;
-import com.cloud.network.vpc.PrivateIpVO;
-import com.cloud.network.vpc.VpcGateway;
-import com.cloud.network.vpc.dao.PrivateIpDao;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-
-@Component
-// This will not be a public service anymore, but a helper for the only public 
service
-@Local(value = {VpcVirtualNetworkHelperImpl.class})
-public class VpcVirtualNetworkHelperImpl {
-
-    @Inject
-    private VMInstanceDao _vmDao;
-    private PrivateIpDao _privateIpDao;
-    @Inject
-    private DomainRouterDao _routerDao;
-    @Inject
-    private NetworkModel _networkModel;
-    @Inject
-    private NicDao _nicDao;
-
-    protected NetworkGeneralHelper nwHelper = new NetworkGeneralHelper();
-
-
-    //@Override
-    public List<DomainRouterVO> getVpcRouters(long vpcId) {
-        return _routerDao.listByVpcId(vpcId);
-    }
-
-    //@Override
-    @DB
-    public NicProfile createPrivateNicProfileForGateway(VpcGateway 
privateGateway) {
-        Network privateNetwork = 
_networkModel.getNetwork(privateGateway.getNetworkId());
-        PrivateIpVO ipVO = 
_privateIpDao.allocateIpAddress(privateNetwork.getDataCenterId(), 
privateNetwork.getId(), privateGateway.getIp4Address());
-        Nic privateNic = 
_nicDao.findByIp4AddressAndNetworkId(ipVO.getIpAddress(), 
privateNetwork.getId());
-
-        NicProfile privateNicProfile = new NicProfile();
-
-        if (privateNic != null) {
-            VirtualMachine vm = _vmDao.findById(privateNic.getInstanceId());
-            privateNicProfile =
-                new NicProfile(privateNic, privateNetwork, 
privateNic.getBroadcastUri(), privateNic.getIsolationUri(), 
_networkModel.getNetworkRate(
-                    privateNetwork.getId(), vm.getId()), 
_networkModel.isSecurityGroupSupportedInNetwork(privateNetwork), 
_networkModel.getNetworkTag(
-                    vm.getHypervisorType(), privateNetwork));
-        } else {
-            String netmask = NetUtils.getCidrNetmask(privateNetwork.getCidr());
-            PrivateIpAddress ip =
-                new PrivateIpAddress(ipVO, 
privateNetwork.getBroadcastUri().toString(), privateNetwork.getGateway(), 
netmask,
-                    
NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(ipVO.getMacAddress())));
-
-            URI netUri = BroadcastDomainType.fromString(ip.getBroadcastUri());
-            privateNicProfile.setIp4Address(ip.getIpAddress());
-            privateNicProfile.setGateway(ip.getGateway());
-            privateNicProfile.setNetmask(ip.getNetmask());
-            privateNicProfile.setIsolationUri(netUri);
-            privateNicProfile.setBroadcastUri(netUri);
-            // can we solve this in setBroadcastUri()???
-            // or more plugable construct is desirable
-            
privateNicProfile.setBroadcastType(BroadcastDomainType.getSchemeValue(netUri));
-            privateNicProfile.setFormat(AddressFormat.Ip4);
-            
privateNicProfile.setReservationId(String.valueOf(ip.getBroadcastUri()));
-            privateNicProfile.setMacAddress(ip.getMacAddress());
-        }
-
-        return privateNicProfile;
-    }
-
-    public NicProfile createGuestNicProfileForVpcRouter(final Network 
guestNetwork) {
-        NicProfile guestNic = new NicProfile();
-        guestNic.setIp4Address(guestNetwork.getGateway());
-        guestNic.setBroadcastUri(guestNetwork.getBroadcastUri());
-        guestNic.setBroadcastType(guestNetwork.getBroadcastDomainType());
-        guestNic.setIsolationUri(guestNetwork.getBroadcastUri());
-        guestNic.setMode(guestNetwork.getMode());
-        String gatewayCidr = guestNetwork.getCidr();
-        guestNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr));
-
-        return guestNic;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/src/com/cloud/network/rules/RuleApplier.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/rules/RuleApplier.java 
b/server/src/com/cloud/network/rules/RuleApplier.java
index 110d5da..04a13e4 100644
--- a/server/src/com/cloud/network/rules/RuleApplier.java
+++ b/server/src/com/cloud/network/rules/RuleApplier.java
@@ -37,7 +37,7 @@ import com.cloud.network.dao.IPAddressDao;
 import com.cloud.network.dao.LoadBalancerDao;
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.lb.LoadBalancingRulesManager;
-import com.cloud.network.router.NetworkGeneralHelper;
+import com.cloud.network.router.NetworkHelper;
 import com.cloud.network.router.RouterControlHelper;
 import com.cloud.network.router.VirtualNetworkApplianceManager;
 import com.cloud.network.router.VirtualRouter;
@@ -110,7 +110,7 @@ public abstract class RuleApplier {
 
     protected RouterControlHelper _routerControlHelper;
 
-    protected NetworkGeneralHelper _networkHelper;
+    protected NetworkHelper _networkHelper;
 
     public RuleApplier(final Network network) {
         _network = network;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java
----------------------------------------------------------------------
diff --git 
a/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java 
b/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java
index 44c4a9f..c545975 100644
--- a/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java
+++ b/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java
@@ -37,7 +37,7 @@ import com.cloud.network.dao.LoadBalancerDao;
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.lb.LoadBalancingRule;
 import com.cloud.network.lb.LoadBalancingRulesManager;
-import com.cloud.network.router.NetworkGeneralHelper;
+import com.cloud.network.router.NetworkHelper;
 import com.cloud.network.router.RouterControlHelper;
 import com.cloud.network.router.VirtualNetworkApplianceManager;
 import com.cloud.network.vpc.NetworkACLItem;
@@ -130,7 +130,7 @@ public class VirtualNetworkApplianceFactory {
     protected IpAddressManager _ipAddrMgr;
 
     @Inject
-    protected NetworkGeneralHelper _networkHelper;
+    protected NetworkHelper _networkHelper;
 
     public LoadBalancingRules createLoadBalancingRules(final Network network, 
final List<LoadBalancingRule> rules) {
         LoadBalancingRules lbRules = new LoadBalancingRules(network, rules);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java
----------------------------------------------------------------------
diff --git 
a/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java 
b/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java
index 2b5ae36..b91707f 100644
--- 
a/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java
+++ 
b/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java
@@ -41,7 +41,7 @@ import com.cloud.network.Networks.TrafficType;
 import com.cloud.network.PublicIpAddress;
 import com.cloud.network.VpnUser;
 import com.cloud.network.lb.LoadBalancingRule;
-import com.cloud.network.router.NetworkGeneralHelper;
+import com.cloud.network.router.NetworkHelper;
 import com.cloud.network.router.VirtualRouter;
 import com.cloud.network.rules.DhcpEntryRules;
 import com.cloud.network.rules.FirewallRule;
@@ -87,7 +87,7 @@ public class BasicNetworkTopology implements NetworkTopology {
     protected HostDao _hostDao;
 
     @Inject
-    protected NetworkGeneralHelper _nwHelper;
+    protected NetworkHelper _nwHelper;
 
     @Inject
     protected UserVmDao _userVmDao;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/src/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java
----------------------------------------------------------------------
diff --git 
a/server/src/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java 
b/server/src/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java
index 5532886..5cdb7d5 100644
--- a/server/src/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java
+++ b/server/src/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java
@@ -32,7 +32,7 @@ import com.cloud.network.Network;
 import com.cloud.network.PublicIpAddress;
 import com.cloud.network.VpnUser;
 import com.cloud.network.lb.LoadBalancingRule;
-import com.cloud.network.router.NetworkGeneralHelper;
+import com.cloud.network.router.NetworkHelper;
 import com.cloud.network.router.VirtualRouter;
 import com.cloud.network.rules.DhcpEntryRules;
 import com.cloud.network.rules.DhcpSubNetRules;
@@ -70,7 +70,7 @@ public class BasicNetworkVisitor extends 
NetworkTopologyVisitor {
     }
 
     @Inject
-    protected NetworkGeneralHelper _networkGeneralHelper;
+    protected NetworkHelper _networkGeneralHelper;
 
     @Override
     public boolean visit(final StaticNatRules nat) throws 
ResourceUnavailableException {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinition.java
----------------------------------------------------------------------
diff --git 
a/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinition.java
 
b/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinition.java
index c8742be..77c7f33 100644
--- 
a/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinition.java
+++ 
b/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinition.java
@@ -52,7 +52,7 @@ import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
 import com.cloud.network.dao.UserIpv6AddressDao;
 import com.cloud.network.dao.VirtualRouterProviderDao;
-import com.cloud.network.router.NetworkGeneralHelper;
+import com.cloud.network.router.NetworkHelper;
 import com.cloud.network.router.VirtualRouter.Role;
 import com.cloud.network.vpc.Vpc;
 import com.cloud.offerings.dao.NetworkOfferingDao;
@@ -90,10 +90,14 @@ public class RouterDeploymentDefinition {
     protected UserIpv6AddressDao ipv6Dao;
     protected IPAddressDao ipAddressDao;
     protected VirtualRouterProvider vrProvider;
+<<<<<<< HEAD
 
 
     @Inject
     protected NetworkGeneralHelper nwHelper;
+=======
+    protected NetworkHelper nwHelper;
+>>>>>>> 40df9d4... Refactor to include network creation as actual deployment
 
 
     protected Network guestNetwork;
@@ -397,7 +401,7 @@ public class RouterDeploymentDefinition {
             LinkedHashMap<Network, List<? extends NicProfile>> networks =
                     this.nwHelper.createRouterNetworks(this);
             //don't start the router as we are holding the network lock that 
needs to be released at the end of router allocation
-            DomainRouterVO router = nwHelper.deployRouter(this, networks, 
false, null);
+            DomainRouterVO router = this.nwHelper.deployRouter(this, networks, 
false, null);
 
             if (router != null) {
                 this.routerDao.addRouterToGuestNetwork(router, 
this.guestNetwork);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinitionBuilder.java
----------------------------------------------------------------------
diff --git 
a/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinitionBuilder.java
 
b/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinitionBuilder.java
index 9f8c0ea..82ea004 100644
--- 
a/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinitionBuilder.java
+++ 
b/server/src/org/cloud/network/router/deployment/RouterDeploymentDefinitionBuilder.java
@@ -36,8 +36,8 @@ import com.cloud.network.dao.PhysicalNetworkDao;
 import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
 import com.cloud.network.dao.UserIpv6AddressDao;
 import com.cloud.network.dao.VirtualRouterProviderDao;
-import com.cloud.network.router.NetworkGeneralHelper;
-import com.cloud.network.router.VpcVirtualNetworkHelperImpl;
+import com.cloud.network.router.NetworkHelper;
+import com.cloud.network.router.VpcNetworkHelper;
 import com.cloud.network.vpc.Vpc;
 import com.cloud.network.vpc.VpcManager;
 import com.cloud.network.vpc.dao.VpcDao;
@@ -93,9 +93,9 @@ public class RouterDeploymentDefinitionBuilder {
     private VlanDao vlanDao;
 
     @Inject
-    protected NetworkGeneralHelper nwHelper;
+    protected NetworkHelper nwHelper;
     @Inject
-    protected VpcVirtualNetworkHelperImpl vpcHelper;
+    protected VpcNetworkHelper vpcNwHelper;
 
     protected Long offeringId;
 
@@ -141,7 +141,7 @@ public class RouterDeploymentDefinitionBuilder {
         routerDeploymentDefinition.pNtwkDao = pNtwkDao;
         routerDeploymentDefinition.vpcMgr = vpcMgr;
         routerDeploymentDefinition.vlanDao = vlanDao;
-        routerDeploymentDefinition.vpcHelper = vpcHelper;
+        routerDeploymentDefinition.vpcHelper = vpcNwHelper;
     }
 
     public class IntermediateStateBuilder {
@@ -206,4 +206,4 @@ public class RouterDeploymentDefinitionBuilder {
             return builder.injectDependencies(routerDeploymentDefinition);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/src/org/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java
----------------------------------------------------------------------
diff --git 
a/server/src/org/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java
 
b/server/src/org/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java
index 8ec05d6..6710a12 100644
--- 
a/server/src/org/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java
+++ 
b/server/src/org/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java
@@ -21,8 +21,6 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
-import javax.inject.Inject;
-
 import org.apache.log4j.Logger;
 
 import com.cloud.dc.dao.VlanDao;
@@ -37,7 +35,7 @@ import com.cloud.network.PhysicalNetwork;
 import com.cloud.network.PhysicalNetworkServiceProvider;
 import com.cloud.network.VirtualRouterProvider.Type;
 import com.cloud.network.dao.PhysicalNetworkDao;
-import com.cloud.network.router.VpcVirtualNetworkHelperImpl;
+import com.cloud.network.router.VpcNetworkHelper;
 import com.cloud.network.vpc.Vpc;
 import com.cloud.network.vpc.VpcManager;
 import com.cloud.network.vpc.dao.VpcDao;
@@ -47,24 +45,22 @@ import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.DomainRouterVO;
 import com.cloud.vm.NicProfile;
 import com.cloud.vm.VirtualMachineProfile.Param;
+import com.cloud.vm.dao.DomainRouterDao;
 
 public class VpcRouterDeploymentDefinition extends RouterDeploymentDefinition {
     private static final Logger logger = 
Logger.getLogger(VpcRouterDeploymentDefinition.class);
 
-    @Inject
-    protected VpcVirtualNetworkHelperImpl vpcHelper;
-
+    protected DomainRouterDao routerDao;
     protected VpcDao vpcDao;
     protected VpcOfferingDao vpcOffDao;
     protected PhysicalNetworkDao pNtwkDao;
     protected VpcManager vpcMgr;
     protected VlanDao vlanDao;
+    protected VpcNetworkHelper vpcNetworkHelper;
 
     protected Vpc vpc;
 
-
-    protected VpcRouterDeploymentDefinition(final Vpc vpc, final 
DeployDestination dest, final Account owner,
-            final Map<Param, Object> params, final boolean isRedundant) {
+    protected VpcRouterDeploymentDefinition(final Vpc vpc, final 
DeployDestination dest, final Account owner, final Map<Param, Object> params, 
final boolean isRedundant) {
 
         super(null, dest, owner, params, isRedundant);
 
@@ -73,7 +69,7 @@ public class VpcRouterDeploymentDefinition extends 
RouterDeploymentDefinition {
 
     @Override
     public Vpc getVpc() {
-        return this.vpc;
+        return vpc;
     }
 
     @Override
@@ -87,16 +83,15 @@ public class VpcRouterDeploymentDefinition extends 
RouterDeploymentDefinition {
         if (vpcLock == null) {
             throw new ConcurrentOperationException("Unable to lock vpc " + 
vpc.getId());
         }
-        this.tableLockId = vpcLock.getId();
+        tableLockId = vpcLock.getId();
     }
 
     @Override
     protected void unlock() {
-        if (this.tableLockId != null) {
-            vpcDao.releaseFromLockTable(this.tableLockId);
+        if (tableLockId != null) {
+            vpcDao.releaseFromLockTable(tableLockId);
             if (logger.isDebugEnabled()) {
-                logger.debug("Lock is released for vpc id " + this.tableLockId
-                        + " as a part of router startup in " + dest);
+                logger.debug("Lock is released for vpc id " + tableLockId + " 
as a part of router startup in " + dest);
             }
         }
     }
@@ -109,19 +104,20 @@ public class VpcRouterDeploymentDefinition extends 
RouterDeploymentDefinition {
     @Override
     protected List<DeployDestination> findDestinations() {
         final List<DeployDestination> destinations = new ArrayList<>();
-        destinations.add(this.dest);
+        destinations.add(dest);
         return destinations;
     }
 
     @Override
     protected int getNumberOfRoutersToDeploy() {
-        // TODO Should we make our changes here in order to enable Redundant 
Router for VPC?
-        return this.routers.isEmpty() ? 1 : 0;
+        // TODO Should we make our changes here in order to enable Redundant
+        // Router for VPC?
+        return routers.isEmpty() ? 1 : 0;
     }
 
     /**
      * @see RouterDeploymentDefinition#prepareDeployment()
-     *
+     * 
      * @return if the deployment can proceed
      */
     @Override
@@ -132,12 +128,13 @@ public class VpcRouterDeploymentDefinition extends 
RouterDeploymentDefinition {
     @Override
     protected void setupPriorityOfRedundantRouter() {
         // Nothing to do for now
-        // TODO Shouldn't we add this behavior once Redundant Router works for 
Vpc too
+        // TODO Shouldn't we add this behavior once Redundant Router works for
+        // Vpc too
     }
 
     @Override
     protected void findSourceNatIP() throws 
InsufficientAddressCapacityException, ConcurrentOperationException {
-        this.sourceNatIp = vpcMgr.assignSourceNatIpAddressToVpc(this.owner, 
vpc);
+        sourceNatIp = vpcMgr.assignSourceNatIpAddressToVpc(owner, vpc);
     }
 
     @Override
@@ -149,8 +146,8 @@ public class VpcRouterDeploymentDefinition extends 
RouterDeploymentDefinition {
             if (provider == null) {
                 throw new CloudRuntimeException("Cannot find service provider 
" + Type.VPCVirtualRouter.toString() + " in physical network " + pNtwk.getId());
             }
-            this.vrProvider = 
vrProviderDao.findByNspIdAndType(provider.getId(), Type.VPCVirtualRouter);
-            if (this.vrProvider != null) {
+            vrProvider = vrProviderDao.findByNspIdAndType(provider.getId(), 
Type.VPCVirtualRouter);
+            if (vrProvider != null) {
                 break;
             }
         }
@@ -160,32 +157,30 @@ public class VpcRouterDeploymentDefinition extends 
RouterDeploymentDefinition {
     protected void findOfferingId() {
         Long vpcOfferingId = 
vpcOffDao.findById(vpc.getVpcOfferingId()).getServiceOfferingId();
         if (vpcOfferingId != null) {
-            this.offeringId = vpcOfferingId;
+            offeringId = vpcOfferingId;
         }
     }
 
     @Override
-    protected void deployAllVirtualRouters()
-            throws ConcurrentOperationException, 
InsufficientCapacityException, ResourceUnavailableException {
+    protected void deployAllVirtualRouters() throws 
ConcurrentOperationException, InsufficientCapacityException, 
ResourceUnavailableException {
 
-        LinkedHashMap<Network, List<? extends NicProfile>> networks = 
this.nwHelper.createVpcRouterNetworks(this);
+        LinkedHashMap<Network, List<? extends NicProfile>> networks = 
vpcNetworkHelper.createRouterNetworks(this);
 
-        DomainRouterVO router =
-                nwHelper.deployRouter(this, networks, true, 
vpcMgr.getSupportedVpcHypervisors());
+        DomainRouterVO router = nwHelper.deployRouter(this, networks, true, 
vpcMgr.getSupportedVpcHypervisors());
 
         if (router != null) {
-            this.routers.add(router);
+            routers.add(router);
         }
     }
 
     @Override
     protected void planDeploymentRouters() {
-        this.routers = this.vpcHelper.getVpcRouters(this.vpc.getId());
+        routers = routerDao.listByVpcId(vpc.getId());
     }
 
     @Override
     protected void generateDeploymentPlan() {
-        final long dcId = this.dest.getDataCenter().getId();
-        this.plan = new DataCenterDeployment(dcId);
+        final long dcId = dest.getDataCenter().getId();
+        plan = new DataCenterDeployment(dcId);
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/test/org/cloud/network/router/deployment/RouterDeploymentDefinitionTestBase.java
----------------------------------------------------------------------
diff --git 
a/server/test/org/cloud/network/router/deployment/RouterDeploymentDefinitionTestBase.java
 
b/server/test/org/cloud/network/router/deployment/RouterDeploymentDefinitionTestBase.java
index 2d9c133..86c6b7d 100644
--- 
a/server/test/org/cloud/network/router/deployment/RouterDeploymentDefinitionTestBase.java
+++ 
b/server/test/org/cloud/network/router/deployment/RouterDeploymentDefinitionTestBase.java
@@ -39,7 +39,7 @@ import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.NetworkVO;
 import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
 import com.cloud.network.dao.VirtualRouterProviderDao;
-import com.cloud.network.router.NetworkGeneralHelper;
+import com.cloud.network.router.NetworkHelper;
 import com.cloud.offerings.NetworkOfferingVO;
 import com.cloud.offerings.dao.NetworkOfferingDao;
 import com.cloud.user.Account;
@@ -73,7 +73,7 @@ public class RouterDeploymentDefinitionTestBase {
     @Mock
     protected DomainRouterDao mockRouterDao;
     @Mock
-    protected NetworkGeneralHelper mockNetworkGeneralHelper;
+    protected NetworkHelper mockNetworkGeneralHelper;
     @Mock
     protected VMInstanceDao mockVmDao;
     @Mock

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a515d6c3/server/test/org/cloud/network/router/deployment/VpcRouterDeploymentDefinitionTest.java
----------------------------------------------------------------------
diff --git 
a/server/test/org/cloud/network/router/deployment/VpcRouterDeploymentDefinitionTest.java
 
b/server/test/org/cloud/network/router/deployment/VpcRouterDeploymentDefinitionTest.java
index a1bb204..3a72fa9 100644
--- 
a/server/test/org/cloud/network/router/deployment/VpcRouterDeploymentDefinitionTest.java
+++ 
b/server/test/org/cloud/network/router/deployment/VpcRouterDeploymentDefinitionTest.java
@@ -36,8 +36,11 @@ import com.cloud.deploy.DeployDestination;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.network.dao.PhysicalNetworkDao;
 import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.router.VpcNetworkHelper;
+import com.cloud.network.vpc.VpcManager;
 import com.cloud.network.vpc.VpcVO;
 import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.network.vpc.dao.VpcOfferingDao;
 import com.cloud.vm.DomainRouterVO;
 
 public class VpcRouterDeploymentDefinitionTest extends 
RouterDeploymentDefinitionTestBase {
@@ -56,116 +59,108 @@ public class VpcRouterDeploymentDefinitionTest extends 
RouterDeploymentDefinitio
     @Mock
     protected VpcVO mockVpc;
 
+    @Mock
+    protected VpcOfferingDao mockVpcOffDao;
+    @Mock
+    protected VpcManager vpcMgr;
+    @Mock
+    protected VpcNetworkHelper vpcHelper;
+
     protected RouterDeploymentDefinition deployment;
 
     @Override
     protected void initMocks() {
         super.initMocks();
-        when(this.mockVpc.getId()).thenReturn(VPC_ID);
-        when(this.mockVpc.getZoneId()).thenReturn(VPC_ID);
+        when(mockVpc.getId()).thenReturn(VPC_ID);
+        when(mockVpc.getZoneId()).thenReturn(VPC_ID);
     }
 
     @Before
     public void initTest() {
-        this.initMocks();
+        initMocks();
 
-        this.deployment = this.builder.create()
-                .setVpc(this.mockVpc)
-                .setDeployDestination(this.mockDestination)
-                .setAccountOwner(this.mockOwner)
-                .setParams(this.params)
-                .build();
+        deployment = 
builder.create().setVpc(mockVpc).setDeployDestination(mockDestination).setAccountOwner(mockOwner).setParams(params).build();
     }
 
     @Test
     public void testConstructionFieldsAndFlags() {
-        assertTrue("Not really a VpcRouterDeploymentDefinition what the 
builder created",
-                this.deployment instanceof VpcRouterDeploymentDefinition);
-        assertTrue("A VpcRouterDeploymentDefinition should declare it is",
-                this.deployment.isVpcRouter());
-        assertEquals("A VpcRouterDeploymentDefinition should have a Vpc",
-                this.mockVpc, this.deployment.getVpc());
+        assertTrue("Not really a VpcRouterDeploymentDefinition what the 
builder created", deployment instanceof VpcRouterDeploymentDefinition);
+        assertTrue("A VpcRouterDeploymentDefinition should declare it is", 
deployment.isVpcRouter());
+        assertEquals("A VpcRouterDeploymentDefinition should have a Vpc", 
mockVpc, deployment.getVpc());
     }
 
     @Test
     public void testLock() {
         // Prepare
-        when(this.mockVpcDao.acquireInLockTable(VPC_ID))
-        .thenReturn(mockVpc);
+        when(mockVpcDao.acquireInLockTable(VPC_ID)).thenReturn(mockVpc);
 
         // Execute
-        this.deployment.lock();
+        deployment.lock();
 
         // Assert
-        verify(this.mockVpcDao, times(1)).acquireInLockTable(VPC_ID);
-        assertNotNull(LOCK_NOT_CORRECTLY_GOT, this.deployment.tableLockId);
-        assertEquals(LOCK_NOT_CORRECTLY_GOT, VPC_ID, 
this.deployment.tableLockId.longValue());
+        verify(mockVpcDao, times(1)).acquireInLockTable(VPC_ID);
+        assertNotNull(LOCK_NOT_CORRECTLY_GOT, deployment.tableLockId);
+        assertEquals(LOCK_NOT_CORRECTLY_GOT, VPC_ID, 
deployment.tableLockId.longValue());
     }
 
     @Test(expected = ConcurrentOperationException.class)
     public void testLockFails() {
         // Prepare
-        when(this.mockVpcDao.acquireInLockTable(VPC_ID))
-        .thenReturn(null);
+        when(mockVpcDao.acquireInLockTable(VPC_ID)).thenReturn(null);
 
         // Execute
         try {
-            this.deployment.lock();
+            deployment.lock();
         } finally {
             // Assert
-            verify(this.mockVpcDao, times(1)).acquireInLockTable(VPC_ID);
-            assertNull(this.deployment.tableLockId);
+            verify(mockVpcDao, times(1)).acquireInLockTable(VPC_ID);
+            assertNull(deployment.tableLockId);
         }
     }
 
     @Test
     public void testUnlock() {
         // Prepare
-        this.deployment.tableLockId = VPC_ID;
+        deployment.tableLockId = VPC_ID;
 
         // Execute
-        this.deployment.unlock();
+        deployment.unlock();
 
         // Assert
-        verify(this.mockVpcDao, times(1)).releaseFromLockTable(VPC_ID);
+        verify(mockVpcDao, times(1)).releaseFromLockTable(VPC_ID);
     }
 
     @Test
     public void testUnlockWithoutLock() {
         // Prepare
-        this.deployment.tableLockId = null;
+        deployment.tableLockId = null;
 
         // Execute
-        this.deployment.unlock();
+        deployment.unlock();
 
         // Assert
-        verify(this.mockVpcDao, times(0)).releaseFromLockTable(anyLong());
+        verify(mockVpcDao, times(0)).releaseFromLockTable(anyLong());
     }
 
     @Test
     public void testFindDestinations() {
         // Execute
-        List<DeployDestination> foundDestinations = 
this.deployment.findDestinations();
+        List<DeployDestination> foundDestinations = 
deployment.findDestinations();
         // Assert
-        assertEquals(FOR_VPC_ONLY_THE_GIVEN_DESTINATION_SHOULD_BE_USED,
-                this.deployment.dest, foundDestinations.get(0));
-        assertEquals(FOR_VPC_ONLY_THE_GIVEN_DESTINATION_SHOULD_BE_USED,
-                1, foundDestinations.size());
+        assertEquals(FOR_VPC_ONLY_THE_GIVEN_DESTINATION_SHOULD_BE_USED, 
deployment.dest, foundDestinations.get(0));
+        assertEquals(FOR_VPC_ONLY_THE_GIVEN_DESTINATION_SHOULD_BE_USED, 1, 
foundDestinations.size());
     }
 
     @Test
     public void testGetNumberOfRoutersToDeploy() {
-        assertEquals("If there are no routers, it should deploy one",
-                1, this.deployment.getNumberOfRoutersToDeploy());
-        this.deployment.routers.add(mock(DomainRouterVO.class));
-        assertEquals("If there is already a router found, there is no need to 
deploy more",
-                0, this.deployment.getNumberOfRoutersToDeploy());
+        assertEquals("If there are no routers, it should deploy one", 1, 
deployment.getNumberOfRoutersToDeploy());
+        deployment.routers.add(mock(DomainRouterVO.class));
+        assertEquals("If there is already a router found, there is no need to 
deploy more", 0, deployment.getNumberOfRoutersToDeploy());
     }
 
     @Test
     public void testPrepareDeployment() {
-        assertTrue("There are no preconditions for Vpc Deployment, thus it 
should always pass",
-                this.deployment.prepareDeployment());
+        assertTrue("There are no preconditions for Vpc Deployment, thus it 
should always pass", deployment.prepareDeployment());
     }
 
     @Test

Reply via email to