From 605239df7278fdb90aca0a7a18312b1ff8e5b5aa Mon Sep 17 00:00:00 2001 From: Abhinandan Prateek Date: Fri, 26 Jun 2015 13:08:28 +0530 Subject: [PATCH] quota: initial commit --- client/pom.xml | 5 + client/tomcatconf/commands.properties.in | 3 + plugins/database/quota/pom.xml | 53 +++++++ .../cloudstack/quota/module.properties | 18 +++ .../cloudstack/quota/spring-quota-context.xml | 31 ++++ .../command/ListQuotaConfigurationsCmd.java | 99 ++++++++++++ .../api/command/QuotaStatementCmd.java | 96 +++++++++++ .../response/QuotaConfigurationResponse.java | 109 +++++++++++++ .../api/response/QuotaStatementResponse.java | 109 +++++++++++++ .../quota/QuotaConfigurationVO.java | 150 ++++++++++++++++++ .../apache/cloudstack/quota/QuotaManager.java | 33 ++++ .../cloudstack/quota/QuotaManagerImpl.java | 80 ++++++++++ .../quota/dao/QuotaConfigurationDao.java | 32 ++++ .../quota/dao/QuotaConfigurationDaoImpl.java | 63 ++++++++ plugins/pom.xml | 1 + setup/db/db/schema-451to452.sql | 48 ++++++ ui/scripts/globalSettings.js | 148 +++++++++++++++++ 17 files changed, 1078 insertions(+) create mode 100644 plugins/database/quota/pom.xml create mode 100644 plugins/database/quota/resources/META-INF/cloudstack/quota/module.properties create mode 100644 plugins/database/quota/resources/META-INF/cloudstack/quota/spring-quota-context.xml create mode 100644 plugins/database/quota/src/org/apache/cloudstack/api/command/ListQuotaConfigurationsCmd.java create mode 100644 plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaStatementCmd.java create mode 100644 plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaConfigurationResponse.java create mode 100644 plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementResponse.java create mode 100644 plugins/database/quota/src/org/apache/cloudstack/quota/QuotaConfigurationVO.java create mode 100644 plugins/database/quota/src/org/apache/cloudstack/quota/QuotaManager.java create mode 100644 plugins/database/quota/src/org/apache/cloudstack/quota/QuotaManagerImpl.java create mode 100644 plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaConfigurationDao.java create mode 100644 plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaConfigurationDaoImpl.java diff --git a/client/pom.xml b/client/pom.xml index 13e1411b971..a3ae8edb4ab 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -356,6 +356,11 @@ cloud-plugin-network-globodns ${project.version} + + org.apache.cloudstack + cloud-plugin-database-quota + ${project.version} + diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index a66a3dce486..82817a538b6 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -781,3 +781,6 @@ listOpenDaylightControllers=1 ### GloboDNS commands addGloboDnsHost=1 + +### Quota Service +listQuotaConfigurations=15 diff --git a/plugins/database/quota/pom.xml b/plugins/database/quota/pom.xml new file mode 100644 index 00000000000..046a9f6cc1b --- /dev/null +++ b/plugins/database/quota/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + cloud-plugin-database-quota + Apache CloudStack Plugin - Quota Service + + org.apache.cloudstack + cloudstack-plugins + 4.5.2-SNAPSHOT + ../../pom.xml + + + + + org.apache.cloudstack + cloud-api + ${project.version} + + + org.apache.cloudstack + cloud-utils + ${project.version} + + + mysql + mysql-connector-java + provided + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + -Xmx1024m + + org/apache/cloudstack/discovery/integration/* + + + + + + diff --git a/plugins/database/quota/resources/META-INF/cloudstack/quota/module.properties b/plugins/database/quota/resources/META-INF/cloudstack/quota/module.properties new file mode 100644 index 00000000000..7332f151828 --- /dev/null +++ b/plugins/database/quota/resources/META-INF/cloudstack/quota/module.properties @@ -0,0 +1,18 @@ +# 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. +name=quota +parent=api diff --git a/plugins/database/quota/resources/META-INF/cloudstack/quota/spring-quota-context.xml b/plugins/database/quota/resources/META-INF/cloudstack/quota/spring-quota-context.xml new file mode 100644 index 00000000000..4c608b45bd8 --- /dev/null +++ b/plugins/database/quota/resources/META-INF/cloudstack/quota/spring-quota-context.xml @@ -0,0 +1,31 @@ + + + + + + + diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/command/ListQuotaConfigurationsCmd.java b/plugins/database/quota/src/org/apache/cloudstack/api/command/ListQuotaConfigurationsCmd.java new file mode 100644 index 00000000000..53200faea57 --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/api/command/ListQuotaConfigurationsCmd.java @@ -0,0 +1,99 @@ +//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 org.apache.cloudstack.api.command; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.BaseListCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.QuotaConfigurationResponse; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.quota.QuotaConfigurationVO; +import org.apache.cloudstack.quota.QuotaManager; + +import com.cloud.user.Account; +import com.cloud.utils.Pair; + +@APICommand(name = "listQuotaConfigurations", responseObject = QuotaConfigurationResponse.class, description = "Lists all Quota and Usage configurations", since = "4.2.0", + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class ListQuotaConfigurationsCmd extends BaseListCmd { + + public static final Logger s_logger = Logger + .getLogger(ListQuotaConfigurationsCmd.class.getName()); + + private static final String s_name = "quotaconfigurationresponse"; + + @Inject + private QuotaManager _quotaManager; + + @Parameter(name = "usageType", type = CommandType.STRING, required = false, description = "Usage type of the resource") + private String _usageType; + + + public ListQuotaConfigurationsCmd() { + super(); + } + + + public ListQuotaConfigurationsCmd(final QuotaManager quotaManager) { + super(); + _quotaManager = quotaManager; + } + + @Override + public void execute() { + final Pair, Integer> result = _quotaManager.listConfigurations(this); + + final List responses = new ArrayList(); + for (final QuotaConfigurationVO resource : result.first()) { + final QuotaConfigurationResponse configurationResponse = _quotaManager.createQuotaConfigurationResponse(resource); + configurationResponse.setObjectName("QuotaConfiguration"); + responses.add(configurationResponse); + } + + final ListResponse response = new ListResponse(); + response.setResponses(responses, responses.size()); + response.setResponseName(getCommandName()); + setResponseObject(response); + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + public String getUsageType() { + return _usageType; + } + + + public void setUsageType(String usageType) { + this._usageType = usageType; + } + + +} diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaStatementCmd.java b/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaStatementCmd.java new file mode 100644 index 00000000000..f349eba1038 --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/api/command/QuotaStatementCmd.java @@ -0,0 +1,96 @@ +//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 org.apache.cloudstack.api.command; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseListCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.DomainResponse; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.quota.QuotaManager; +import org.apache.cloudstack.api.response.QuotaStatementResponse; + +import com.cloud.user.Account; + +@APICommand(name = "quotaStatement", responseObject = QuotaStatementResponse.class, description = "Create a quota statement", since = "4.2.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class QuotaStatementCmd extends BaseListCmd { + + public static final Logger s_logger = Logger + .getLogger(QuotaStatementCmd.class.getName()); + + private static final String s_name = "quotastatementresponse"; + + @Inject + private QuotaManager _quotaManager; + + @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Optional, Account Id for which statement needs to be generated") + private String accountName; + + @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "Optional, If domain Id is given and the caller is domain admin then the statement is generated for domain.") + private Long domainId; + + + public QuotaStatementCmd() { + super(); + } + + + public QuotaStatementCmd(final QuotaManager quotaManager) { + super(); + _quotaManager = quotaManager; + } + + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Long accountId = _accountService.finalyzeAccountId(accountName, domainId, null, true); + if (accountId == null) { + return CallContext.current().getCallingAccount().getId(); + } + return Account.ACCOUNT_ID_SYSTEM; + } + + + @Override + public void execute() { + /**final Pair, Integer> result = _quotaManager.listConfigurations(this); + + final List responses = new ArrayList(); + for (final QuotaConfigurationVO resource : result.first()) { + final QuotaStatementResponse configurationResponse = _quotaManager.createQuotaConfigurationResponse(resource); + configurationResponse.setObjectName("QuotaConfiguration"); + responses.add(configurationResponse); + }**/ + + final ListResponse response = new ListResponse(); + //response.setResponses(responses, responses.size()); + response.setResponseName(getCommandName()); + setResponseObject(response); + } + + +} diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaConfigurationResponse.java b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaConfigurationResponse.java new file mode 100644 index 00000000000..0e34988c8fd --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaConfigurationResponse.java @@ -0,0 +1,109 @@ +//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 org.apache.cloudstack.api.response; + +import com.google.gson.annotations.SerializedName; + +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; + +public class QuotaConfigurationResponse extends BaseResponse { + + @SerializedName("usageType") + @Param(description = "usageType") + private String usageType; + + @SerializedName("usageUnit") + @Param(description = "usageUnit") + private String usageUnit; + + @SerializedName("usageDiscriminator") + @Param(description = "usageDiscriminator") + private String usageDiscriminator; + + @SerializedName("currencyValue") + @Param(description = "currencyValue") + private int currencyValue; + + @SerializedName("include") + @Param(description = "include") + private int include; + + @SerializedName("description") + @Param(description = "description") + private String description; + + + public QuotaConfigurationResponse() { + super(); + } + + public QuotaConfigurationResponse(final String usageType) { + super(); + this.usageType = usageType; + } + + public String getUsageType() { + return usageType; + } + + public void setUsageType(String usageType) { + this.usageType = usageType; + } + + public String getUsageUnit() { + return usageUnit; + } + + public void setUsageUnit(String usageUnit) { + this.usageUnit = usageUnit; + } + + public String getUsageDiscriminator() { + return usageDiscriminator; + } + + public void setUsageDiscriminator(String usageDiscriminator) { + this.usageDiscriminator = usageDiscriminator; + } + + public int getCurrencyValue() { + return currencyValue; + } + + public void setCurrencyValue(int currencyValue) { + this.currencyValue = currencyValue; + } + + public int getInclude() { + return include; + } + + public void setInclude(int include) { + this.include = include; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementResponse.java b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementResponse.java new file mode 100644 index 00000000000..e0598a8df6e --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementResponse.java @@ -0,0 +1,109 @@ +//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 org.apache.cloudstack.api.response; + +import com.google.gson.annotations.SerializedName; + +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; + +public class QuotaStatementResponse extends BaseResponse { + + @SerializedName("usageType") + @Param(description = "usageType") + private String usageType; + + @SerializedName("usageUnit") + @Param(description = "usageUnit") + private String usageUnit; + + @SerializedName("usageDiscriminator") + @Param(description = "usageDiscriminator") + private String usageDiscriminator; + + @SerializedName("currencyValue") + @Param(description = "currencyValue") + private int currencyValue; + + @SerializedName("include") + @Param(description = "include") + private int include; + + @SerializedName("description") + @Param(description = "description") + private String description; + + + public QuotaStatementResponse() { + super(); + } + + public QuotaStatementResponse(final String usageType) { + super(); + this.usageType = usageType; + } + + public String getUsageType() { + return usageType; + } + + public void setUsageType(String usageType) { + this.usageType = usageType; + } + + public String getUsageUnit() { + return usageUnit; + } + + public void setUsageUnit(String usageUnit) { + this.usageUnit = usageUnit; + } + + public String getUsageDiscriminator() { + return usageDiscriminator; + } + + public void setUsageDiscriminator(String usageDiscriminator) { + this.usageDiscriminator = usageDiscriminator; + } + + public int getCurrencyValue() { + return currencyValue; + } + + public void setCurrencyValue(int currencyValue) { + this.currencyValue = currencyValue; + } + + public int getInclude() { + return include; + } + + public void setInclude(int include) { + this.include = include; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaConfigurationVO.java b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaConfigurationVO.java new file mode 100644 index 00000000000..fd685b0ac70 --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaConfigurationVO.java @@ -0,0 +1,150 @@ +//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 org.apache.cloudstack.quota; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.InternalIdentity; + +@Entity +@Table(name = "quota_configuration") +public class QuotaConfigurationVO implements InternalIdentity { + /** + * enable.quota.service: Enable quota service by default all of this + * functionality is disabled. quota.period.type : Quota period type: 1 for + * every x days, 2 for certain day of the month, 3 for yearly on activation + * day - default usage reporting cycle quota.period.config : The value for + * the above quota period type quota.activity.generate : Set “Y” to enable a + * detailed log of the quota usage, rating and billing activity, on daily + * basis. Valid values (“Y”, “N”); record.outgoingEmail: Boolean, yes means + * all the emails sent out will be stored in local DB, by default it is no. + * quota.enable : enable the usage quota enforcement quota.currencySymbol : + * The symbol for the currency in use to measure usage. quota.criticalLimit: + * A limit when it is reached user is sent and alert. + * quota.incrementalLimit: A incremental limit that is added to + * criticalLimit in this increments, when breached a email is send to the + * user with details. + * */ + + private static final long serialVersionUID = -7117933766387653203L; + + @Id + @Column(name = "id") + private Long id; + + @Column(name = "usage_type") + private String usageType; + + @Column(name = "usage_unit") + private String usageUnit; + + @Column(name = "usage_discriminator") + private String usageDiscriminator; + + @Column(name = "currency_value") + private int currencyValue; + + @Column(name = "include") + private int include; + + @Column(name = "description") + private String description; + + + public QuotaConfigurationVO() { + } + + + public QuotaConfigurationVO(final String usagetype, final String usageunit, final String usagediscriminator, final int currencyvalue, final int include, final String description) { + this.usageType = usagetype; + this.usageUnit = usageunit; + this.usageDiscriminator = usagediscriminator; + this.currencyValue = currencyvalue; + this.include = include; + this.description = description; + } + + + public String getUsageType() { + return usageType; + } + + + public void setUsageType(String usageType) { + this.usageType = usageType; + } + + + public String getUsageUnit() { + return usageUnit; + } + + + public void setUsageUnit(String usageUnit) { + this.usageUnit = usageUnit; + } + + + public String getUsageDiscriminator() { + return usageDiscriminator; + } + + + public void setUsageDiscriminator(String usageDiscriminator) { + this.usageDiscriminator = usageDiscriminator; + } + + + public int getCurrencyValue() { + return currencyValue; + } + + + public void setCurrencyValue(int currencyValue) { + this.currencyValue = currencyValue; + } + + + public int getInclude() { + return include; + } + + + public void setInclude(int include) { + this.include = include; + } + + + public String getDescription() { + return description; + } + + + public void setDescription(String description) { + this.description = description; + } + + + @Override + public long getId() { + // TODO Auto-generated method stub + return this.id; + } +} \ No newline at end of file diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaManager.java b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaManager.java new file mode 100644 index 00000000000..cf29064323e --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaManager.java @@ -0,0 +1,33 @@ +//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 org.apache.cloudstack.quota; + +import java.util.List; + +import org.apache.cloudstack.api.command.ListQuotaConfigurationsCmd; +import org.apache.cloudstack.api.response.QuotaConfigurationResponse; + +import com.cloud.utils.Pair; +import com.cloud.utils.component.PluggableService; + +public interface QuotaManager extends PluggableService { + + Pair, Integer> listConfigurations(ListQuotaConfigurationsCmd cmd); + + QuotaConfigurationResponse createQuotaConfigurationResponse(QuotaConfigurationVO configuration); + +} diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaManagerImpl.java b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaManagerImpl.java new file mode 100644 index 00000000000..8a4fbd4f65b --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaManagerImpl.java @@ -0,0 +1,80 @@ +//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 org.apache.cloudstack.quota; + +import java.util.ArrayList; +import java.util.List; + +import javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.cloudstack.api.command.ListQuotaConfigurationsCmd; +import org.apache.cloudstack.api.response.QuotaConfigurationResponse; +import org.apache.cloudstack.quota.dao.QuotaConfigurationDao; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.utils.Pair; + +@Component +@Local(value = QuotaManager.class) +public class QuotaManagerImpl implements QuotaManager { + private static final Logger s_logger = Logger.getLogger(QuotaManagerImpl.class.getName()); + + + @Inject + private QuotaConfigurationDao _quotaConfigurationDao; + + + + public QuotaManagerImpl() { + super(); + } + + public QuotaManagerImpl(final QuotaConfigurationDao quotaConfigurationDao) { + super(); + _quotaConfigurationDao = quotaConfigurationDao; + } + + + @Override + public List> getCommands() { + final List> cmdList = new ArrayList>(); + cmdList.add(ListQuotaConfigurationsCmd.class); + return cmdList; + } + + @Override + public Pair, Integer> listConfigurations(final ListQuotaConfigurationsCmd cmd) { + final Pair, Integer> result = _quotaConfigurationDao.searchConfigurations(); + return result; + } + + + @Override + public QuotaConfigurationResponse createQuotaConfigurationResponse(final QuotaConfigurationVO configuration) { + final QuotaConfigurationResponse response = new QuotaConfigurationResponse(); + response.setUsageType(configuration.getUsageType()); + response.setUsageUnit(configuration.getUsageUnit()); + response.setUsageDiscriminator(configuration.getUsageDiscriminator()); + response.setCurrencyValue(configuration.getCurrencyValue()); + response.setInclude(configuration.getInclude()); + response.setDescription(configuration.getDescription()); + return response; + } + +} diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaConfigurationDao.java b/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaConfigurationDao.java new file mode 100644 index 00000000000..324e7d9e89e --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaConfigurationDao.java @@ -0,0 +1,32 @@ +//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 org.apache.cloudstack.quota.dao; + +import java.util.List; + +import org.apache.cloudstack.quota.QuotaConfigurationVO; + +import com.cloud.utils.Pair; +import com.cloud.utils.db.GenericDao; + +public interface QuotaConfigurationDao extends GenericDao { + + QuotaConfigurationVO findByUsageType(String usageType); + + Pair, Integer> searchConfigurations(); + +} diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaConfigurationDaoImpl.java b/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaConfigurationDaoImpl.java new file mode 100644 index 00000000000..eafc9eace99 --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/quota/dao/QuotaConfigurationDaoImpl.java @@ -0,0 +1,63 @@ +//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 org.apache.cloudstack.quota.dao; + +import java.util.List; + +import javax.ejb.Local; + +import org.springframework.stereotype.Component; +import org.apache.cloudstack.quota.QuotaConfigurationVO; + +import com.cloud.utils.Pair; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +@Component +@Local(value = {QuotaConfigurationDao.class}) +public class QuotaConfigurationDaoImpl extends GenericDaoBase implements QuotaConfigurationDao { + private final SearchBuilder searchUsageType; + private final SearchBuilder listAllIncludedUsageType; + + public QuotaConfigurationDaoImpl() { + super(); + searchUsageType = createSearchBuilder(); + searchUsageType.and("usage_type", searchUsageType.entity().getUsageType(), SearchCriteria.Op.EQ); + searchUsageType.done(); + + listAllIncludedUsageType = createSearchBuilder(); + listAllIncludedUsageType.and("include", listAllIncludedUsageType.entity().getInclude(), SearchCriteria.Op.EQ); + listAllIncludedUsageType.done(); + } + + @Override + public QuotaConfigurationVO findByUsageType(final String usageType) { + final SearchCriteria sc = searchUsageType.create(); + sc.setParameters("usage_type", usageType); + return findOneBy(sc); + } + + @Override + public Pair, Integer> searchConfigurations() { + final SearchCriteria sc = listAllIncludedUsageType.create(); + sc.setParameters("include", 1); + return searchAndCount(sc, null); + } + + +} diff --git a/plugins/pom.xml b/plugins/pom.xml index 6c826600c48..0c7c2fcda9a 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -90,6 +90,7 @@ network-elements/internal-loadbalancer network-elements/vxlan network-elements/globodns + database/quota diff --git a/setup/db/db/schema-451to452.sql b/setup/db/db/schema-451to452.sql index 5c89008a83e..cdf6e5b1b6b 100644 --- a/setup/db/db/schema-451to452.sql +++ b/setup/db/db/schema-451to452.sql @@ -19,6 +19,8 @@ -- Schema upgrade from 4.5.1 to 4.5.2; --; +-- SAML + DELETE FROM `cloud`.`configuration` WHERE name like 'saml%'; ALTER TABLE `cloud`.`user` ADD COLUMN `external_entity` text DEFAULT NULL COMMENT "reference to external federation entity"; @@ -33,3 +35,49 @@ CREATE TABLE `cloud`.`saml_token` ( PRIMARY KEY (`id`), CONSTRAINT `fk_saml_token__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Quota Configuration + +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.enable.service' , 'true', 'false', 'Enable or Disable Quota service'); +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.period.type' , '2', '2', 'Quota period type: 1 for every x days, 2 for certain day of the month, 3 for yearly on activation day - default quota usage reporting cycle'); +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.period.config' , '15', '15', 'The period config in number of days for the quota period type'); +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.activity.generate' , 'true', 'false', 'Set true to enable a detailed log of the quota usage, rating and billing activity, on daily basis. Valid values (true, false)'); +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.email.outgoing.record' , 'true', 'false', 'true means all the emails sent out will be stored in local DB, by default it is false'); +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.enable.enforcement' , 'true', 'false', ' Enable the usage quota enforcement, i.e. on true exceeding quota the respective account will be locked.'); +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.currency.symbol' , 'R', 'C', ' The symbol for the currency in use to measure usage.'); +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.limit.critical' , '80', '80', 'A percentage limit for quota when it is reached user is sent and alert.'); +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.limit.increment' , '5', '5', 'A percentage incremental limit that is added to criticalLimit in this increments, when breached a email is send to the user with details'); + +-- Quota Emailer + +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.usage.smtp.host' , '', '', 'SMTP host to for email'); +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.usage.smtp.connection.timeout' , '60', '60', 'SMTP server timeout in seconds'); +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.usage.smtp.user' , '', '', 'SMTP user'); +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.usage.smtp.password' , '', '', 'SMTP Password'); +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.usage.smtp.port' , '', '', 'SMTP port'); +INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'QuotaService', 'quota.usage.smtp.useAuth' , '', '', 'SMTP Auth type'); + +CREATE TABLE `cloud`.`quota_configuration` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `usage_type` varchar(255) NOT NULL COMMENT 'usage type', + `usage_unit` varchar(255) NOT NULL COMMENT 'usage type', + `usage_discriminator` varchar(255) NOT NULL COMMENT 'usage type', + `currency_value` varchar(255) NOT NULL COMMENT 'usage type', + `include` BOOLEAN NOT NULL COMMENT 'usage type', + `description` varchar(255) NOT NULL COMMENT 'usage type', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +INSERT IGNORE INTO `cloud`.`quota_configuration` (`usage_type`, `usage_unit`, `usage_discriminator`, `currency_value`, `include`, `description`) VALUES ('RUNNING_VM', 'Compute-Hours', '', '5' , '1', 'Quota mapping for running VM'); +INSERT IGNORE INTO `cloud`.`quota_configuration` (`usage_type`, `usage_unit`, `usage_discriminator`, `currency_value`, `include`, `description`) VALUES ('ALLOCATED_VM', 'Compute-Hours', '', '1' , '1', 'Quota mapping for running VM'); +INSERT IGNORE INTO `cloud`.`quota_configuration` (`usage_type`, `usage_unit`, `usage_discriminator`, `currency_value`, `include`, `description`) VALUES ('IP_ADDRESS', 'IP-Hours', '', '0.1' , '1', 'Quota mapping for running VM'); +INSERT IGNORE INTO `cloud`.`quota_configuration` (`usage_type`, `usage_unit`, `usage_discriminator`, `currency_value`, `include`, `description`) VALUES ('NETWORK_BYTES_SENT', 'GB', '', '1' , '1', 'Quota mapping for running VM'); +INSERT IGNORE INTO `cloud`.`quota_configuration` (`usage_type`, `usage_unit`, `usage_discriminator`, `currency_value`, `include`, `description`) VALUES ('NETWORK_BYTES_RECEIVED', 'GB', '', '1' , '1', 'Quota mapping for running VM'); +INSERT IGNORE INTO `cloud`.`quota_configuration` (`usage_type`, `usage_unit`, `usage_discriminator`, `currency_value`, `include`, `description`) VALUES ('VOLUME', 'GB-Month', '', '5' , '1', 'Quota mapping for running VM'); +INSERT IGNORE INTO `cloud`.`quota_configuration` (`usage_type`, `usage_unit`, `usage_discriminator`, `currency_value`, `include`, `description`) VALUES ('TEMPLATE', 'GB-Month', '', '5' , '1', 'Quota mapping for running VM'); +INSERT IGNORE INTO `cloud`.`quota_configuration` (`usage_type`, `usage_unit`, `usage_discriminator`, `currency_value`, `include`, `description`) VALUES ('ISO', 'GB-Month', '', '5' , '1', 'Quota mapping for running VM'); +INSERT IGNORE INTO `cloud`.`quota_configuration` (`usage_type`, `usage_unit`, `usage_discriminator`, `currency_value`, `include`, `description`) VALUES ('SNAPSHOT', 'GB-Month', '', '5' , '1', 'Quota mapping for running VM'); +INSERT IGNORE INTO `cloud`.`quota_configuration` (`usage_type`, `usage_unit`, `usage_discriminator`, `currency_value`, `include`, `description`) VALUES ('LOAD_BALANCER_POLICY', 'Policy-Hours', '', '5' , '0', 'Quota mapping for running VM'); +INSERT IGNORE INTO `cloud`.`quota_configuration` (`usage_type`, `usage_unit`, `usage_discriminator`, `currency_value`, `include`, `description`) VALUES ('PORT_FORWARDING_RULE', 'Policy-Hours', '', '5' , '0', 'Quota mapping for running VM'); +INSERT IGNORE INTO `cloud`.`quota_configuration` (`usage_type`, `usage_unit`, `usage_discriminator`, `currency_value`, `include`, `description`) VALUES ('NETWORK_OFFERING', 'Policy-Hours', '', '5' , '0', 'Quota mapping for running VM'); diff --git a/ui/scripts/globalSettings.js b/ui/scripts/globalSettings.js index 34d65a2a593..ad0fecaa358 100644 --- a/ui/scripts/globalSettings.js +++ b/ui/scripts/globalSettings.js @@ -100,6 +100,154 @@ } } }, + quotaConfiguration: { + type: 'select', + title: 'label.quota.configuration', + listView: { + id: 'quota', + label: 'label.quota.configuration', + fields: { + usageType: { + label: 'label.usage.type' + }, + usageUnit: { + label: 'label.usgae.unit' + }, + currencyValue: { + label: 'label.quota.value' + }, + description: { + label: 'label.quota.description' + } + + }, + dataProvider: function(args) { + var data = {}; + listViewDataProvider(args, data); + $.ajax({ + url: createURL('listQuotaConfigurations'), + data: data, + success: function(json) { + var items = json.quotaconfigurationresponse.QuotaConfiguration; + args.response.success({ + data: items + }); + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); + } + }); + }, + detailView: { + name: 'label.details', + actions: { + remove: { + label: 'label.remove.quota', + messages: { + notification: function(args) { + return 'label.remove.quota'; + }, + confirm: function() { + return 'message.remove.quota'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("deleteQuotaConfiguration&hostname=" + args.context.quotaConfiguration[0].hostname), + success: function(json) { + args.response.success(); + } + }); + $(window).trigger('cloudStack.fullRefresh'); + } + } + }, + tabs: { + details: { + title: 'label.quota.configuration', + fields: [{ + usageType: { + label: 'label.usage.type' + }, + usageUnit: { + label: 'label.usgae.unit' + }, + currencyValue: { + label: 'label.quota.value' + }, + description: { + label: 'label.quota.description' + } + }], + dataProvider: function(args) { + var items = []; + console.log(args); + $.ajax({ + url: createURL("listQuotaConfigurations&hostname=" + args.context.quotaConfiguration[0].hostname), + dataType: "json", + async: true, + success: function(json) { + var item = json.quotaconfigurationresponse.QuotaConfiguration; + args.response.success({ + data: item[0] + }); + } + }); + } + } + } + }, + actions: { + add: { + label: 'label.configure.quota', + messages: { + confirm: function(args) { + return 'message.configure.quota'; + }, + notification: function(args) { + return 'label.configure.quota'; + } + }, + createForm: { + title: 'label.configure.quota', + fields: { + hostname: { + label: 'label.host.name', + validation: { + required: true + } + }, + port: { + label: 'label.port', + validation: { + required: true + } + } + } + }, + action: function(args) { + var array = []; + array.push("&hostname=" + todb(args.data.hostname)); + array.push("&port=" + todb(args.data.port));; + $.ajax({ + url: createURL("addQuotaConfiguration" + array.join("")), + dataType: "json", + async: true, + success: function(json) { + var items = json.quotaconfigurationresponse.QuotaAddConfiguration; + args.response.success({ + data: items + }); + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + } + } + } + } + }, ldapConfiguration: { type: 'select', title: 'label.ldap.configuration',