@Override
  public boolean applyLBRules(final Network network, final List<LoadBalancingRule> rules)
      throws ResourceUnavailableException {
    boolean result = true;
    if (canHandle(network, Service.Lb)) {
      if (!canHandleLbRules(rules)) {
        return false;
      }

      final List<DomainRouterVO> routers =
          _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
      if (routers == null || routers.isEmpty()) {
        s_logger.debug(
            "Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual "
                + "router doesn't exist in the network "
                + network.getId());
        return true;
      }

      final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
      final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);

      for (final DomainRouterVO domainRouterVO : routers) {
        result = result && networkTopology.applyLoadBalancingRules(network, rules, domainRouterVO);
        if (!result) {
          s_logger.debug("Failed to apply load balancing rules in network " + network.getId());
        }
      }
    }
    return result;
  }
  @Override
  public boolean applyIps(
      final Network network,
      final List<? extends PublicIpAddress> ipAddress,
      final Set<Service> services)
      throws ResourceUnavailableException {
    boolean canHandle = true;
    for (final Service service : services) {
      // check if Ovs can handle services except SourceNat & Firewall
      if (!canHandle(network, service)
          && service != Service.SourceNat
          && service != Service.Firewall) {
        canHandle = false;
        break;
      }
    }
    boolean result = true;
    if (canHandle) {
      final List<DomainRouterVO> routers =
          _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
      if (routers == null || routers.isEmpty()) {
        s_logger.debug(
            "Virtual router element doesn't need to associate ip addresses on the backend; virtual "
                + "router doesn't exist in the network "
                + network.getId());
        return true;
      }

      final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
      final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);

      for (final DomainRouterVO domainRouterVO : routers) {
        result = result && networkTopology.associatePublicIP(network, ipAddress, domainRouterVO);
      }
    }
    return result;
  }
  @Override
  public boolean applyStaticNats(final Network network, final List<? extends StaticNat> rules)
      throws ResourceUnavailableException {
    if (!canHandle(network, Service.StaticNat)) {
      return false;
    }
    final List<DomainRouterVO> routers =
        _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
    if (routers == null || routers.isEmpty()) {
      s_logger.debug(
          "Ovs element doesn't need to apply static nat on the backend; virtual "
              + "router doesn't exist in the network "
              + network.getId());
      return true;
    }

    final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
    final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO);
    boolean result = true;
    for (final DomainRouterVO domainRouterVO : routers) {
      result = result && networkTopology.applyStaticNats(network, rules, domainRouterVO);
    }
    return result;
  }