class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingRulesService {

    @Override
    @DB
    @ActionEvent(eventType = EventTypes.EVENT_GLOBAL_LOAD_BALANCER_CREATE, eventDescription = "creating global load " + "balancer rule", create = true)
    public GlobalLoadBalancerRule createGlobalLoadBalancerRule(CreateGlobalLoadBalancerRuleCmd newRule) {

        final Integer regionId = newRule.getRegionId();
        final String algorithm = newRule.getAlgorithm();
        final String stickyMethod = newRule.getStickyMethod();
        final String name = newRule.getName();
        final String description = newRule.getDescription();
        final String domainName = newRule.getServiceDomainName();
        final String serviceType = newRule.getServiceType();

        final Account gslbOwner = _accountMgr.getAccount(newRule.getEntityOwnerId());

        if (!GlobalLoadBalancerRule.Algorithm.isValidAlgorithm(algorithm)) {
            throw new InvalidParameterValueException("Invalid Algorithm: " + algorithm);
        }

        if (!GlobalLoadBalancerRule.Persistence.isValidPersistence(stickyMethod)) {
            throw new InvalidParameterValueException("Invalid persistence: " + stickyMethod);
        }

        if (!GlobalLoadBalancerRule.ServiceType.isValidServiceType(serviceType)) {
            throw new InvalidParameterValueException("Invalid service type: " + serviceType);
        }

        if (!NetUtils.verifyDomainName(domainName)) {
            throw new InvalidParameterValueException("Invalid domain name : " + domainName);
        }

        GlobalLoadBalancerRuleVO gslbRuleWithDomainName = _gslbRuleDao.findByDomainName(domainName);
        if (gslbRuleWithDomainName != null) {
            throw new InvalidParameterValueException("Domain name " + domainName + "is in use");
        }

        Region region = _regionDao.findById(regionId);
        if (region == null) {
            throw new InvalidParameterValueException("Invalid region ID: " + regionId);
        }

        String providerDnsName = _globalConfigDao.getValue(Config.CloudDnsName.key());
        if (!region.checkIfServiceEnabled(Region.Service.Gslb) || (providerDnsName == null)) {
            throw new CloudRuntimeException("GSLB service is not enabled in region : " + region.getName());
        }

        GlobalLoadBalancerRuleVO newGslbRule = Transaction.execute(new TransactionCallback<GlobalLoadBalancerRuleVO>() {
            @Override
            public GlobalLoadBalancerRuleVO doInTransaction(TransactionStatus status) {
                GlobalLoadBalancerRuleVO newGslbRule =
                    new GlobalLoadBalancerRuleVO(name, description, domainName, algorithm, stickyMethod, serviceType, regionId, gslbOwner.getId(),
                        gslbOwner.getDomainId(), GlobalLoadBalancerRule.State.Staged);
                _gslbRuleDao.persist(newGslbRule);

                UsageEventUtils.publishUsageEvent(EventTypes.EVENT_GLOBAL_LOAD_BALANCER_CREATE, newGslbRule.getAccountId(), 0, newGslbRule.getId(), name,
                    GlobalLoadBalancerRule.class.getName(), newGslbRule.getUuid());

                return newGslbRule;
            }
        });

        s_logger.debug("successfully created new global load balancer rule for the account " + gslbOwner.getId());

        return newGslbRule;
    }

}