package com.sequenceiq.cloudbreak.service.account; import java.util.Calendar; import java.util.List; import java.util.Set; import javax.inject.Inject; import org.springframework.stereotype.Component; import com.sequenceiq.cloudbreak.domain.AccountPreferences; import com.sequenceiq.cloudbreak.domain.CbUser; import com.sequenceiq.cloudbreak.domain.InstanceGroup; import com.sequenceiq.cloudbreak.domain.Stack; import com.sequenceiq.cloudbreak.service.stack.StackService; import com.sequenceiq.cloudbreak.service.user.UserDetailsService; import com.sequenceiq.cloudbreak.service.user.UserFilterField; @Component public class AccountPreferencesValidator { private static final Long EXTREMAL_VALUE = 0L; @Inject private AccountPreferencesService accountPreferencesService; @Inject private StackService stackService; @Inject private UserDetailsService userDetailsService; public void validate(Stack stack, String account, String owner) throws AccountPreferencesValidationFailed { validate(stack.getInstanceGroups(), stack.getFullNodeCount(), account, owner); } public void validate(Long stackId, Integer scalingAdjustment) throws AccountPreferencesValidationFailed { Stack stack = stackService.getById(stackId); Integer newNodeCount = stack.getFullNodeCount() + scalingAdjustment; validate(stack.getInstanceGroups(), newNodeCount, stack.getAccount(), stack.getOwner()); } private void validate(Set<InstanceGroup> instanceGroups, Integer nodeCount, String account, String owner) throws AccountPreferencesValidationFailed { AccountPreferences preferences = accountPreferencesService.getByAccount(account); validateNumberOfNodesPerCluster(nodeCount, preferences); validateNumberOfClusters(account, preferences); validateAllowedInstanceTypes(instanceGroups, preferences); validateNumberOfClustersPerUser(owner, preferences); validateUserTimeToLive(owner, preferences); } private void validateNumberOfNodesPerCluster(Integer nodeCount, AccountPreferences preferences) throws AccountPreferencesValidationFailed { Long maxNodeNumberPerCluster = preferences.getMaxNumberOfNodesPerCluster(); if (needToValidateField(maxNodeNumberPerCluster) && nodeCount > maxNodeNumberPerCluster) { throw new AccountPreferencesValidationFailed(String.format("Cluster with maximum '%s' instances could be created within this account!", maxNodeNumberPerCluster)); } } private void validateNumberOfClusters(String account, AccountPreferences preferences) throws AccountPreferencesValidationFailed { Long maxNumberOfClusters = preferences.getMaxNumberOfClusters(); if (needToValidateField(maxNumberOfClusters)) { Set<Stack> stacks = stackService.retrieveAccountStacks(account); if (stacks.size() >= maxNumberOfClusters) { throw new AccountPreferencesValidationFailed( String.format("No more cluster could be created! The number of clusters exceeded the account's limit(%s)!", maxNumberOfClusters)); } } } private void validateAllowedInstanceTypes(Set<InstanceGroup> instanceGroups, AccountPreferences preferences) throws AccountPreferencesValidationFailed { List<String> allowedInstanceTypes = preferences.getAllowedInstanceTypes(); if (needToValidateField(allowedInstanceTypes)) { for (InstanceGroup ig : instanceGroups) { String instanceTypeName = ig.getTemplate().getInstanceType(); if (!allowedInstanceTypes.contains(instanceTypeName)) { throw new AccountPreferencesValidationFailed( String.format("The '%s' instance type isn't allowed within the account!", instanceTypeName)); } } } } private void validateNumberOfClustersPerUser(String owner, AccountPreferences preferences) throws AccountPreferencesValidationFailed { Long maxClustersPerUser = preferences.getMaxNumberOfClustersPerUser(); if (needToValidateField(maxClustersPerUser)) { Set<Stack> stacks = stackService.retrieveOwnerStacks(owner); if (stacks.size() >= maxClustersPerUser) { throw new AccountPreferencesValidationFailed( String.format("No more cluster could be created! The number of clusters exceeded the user's limit(%s)!", maxClustersPerUser)); } } } public void validateUserTimeToLive(String owner, AccountPreferences preferences) throws AccountPreferencesValidationFailed { Long userTimeToLive = preferences.getUserTimeToLive(); if (needToValidateField(userTimeToLive)) { CbUser cbUser = userDetailsService.getDetails(owner, UserFilterField.USERID); long now = Calendar.getInstance().getTimeInMillis(); long userActiveTime = now - cbUser.getCreated().getTime(); if (userActiveTime > userTimeToLive) { throw new AccountPreferencesValidationFailed("The user demo time is expired!"); } } } public void validateClusterTimeToLive(Long created, Long clusterTimeToLive) throws AccountPreferencesValidationFailed { if (needToValidateField(clusterTimeToLive)) { long now = Calendar.getInstance().getTimeInMillis(); long clusterRunningTime = now - created; if (clusterRunningTime > clusterTimeToLive) { throw new AccountPreferencesValidationFailed("The maximum running time that is configured for the account is exceeded by the cluster!"); } } } private boolean needToValidateField(Long field) { return field != null && !EXTREMAL_VALUE.equals(field); } private boolean needToValidateField(List<String> field) { return field != null && !field.isEmpty(); } }