diff --git a/api/src/main/java/com/cloud/event/EventTypes.java b/api/src/main/java/com/cloud/event/EventTypes.java index f7678d99d32..f579fdb23f1 100644 --- a/api/src/main/java/com/cloud/event/EventTypes.java +++ b/api/src/main/java/com/cloud/event/EventTypes.java @@ -29,6 +29,7 @@ import org.apache.cloudstack.api.response.PodResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.config.Configuration; import org.apache.cloudstack.ha.HAConfig; +import org.apache.cloudstack.quota.QuotaTariff; import org.apache.cloudstack.usage.Usage; import com.cloud.dc.DataCenter; @@ -693,6 +694,11 @@ public class EventTypes { // SystemVM public static final String EVENT_LIVE_PATCH_SYSTEMVM = "LIVE.PATCH.SYSTEM.VM"; + // Quota + public static final String EVENT_QUOTA_TARIFF_CREATE = "QUOTA.TARIFF.CREATE"; + public static final String EVENT_QUOTA_TARIFF_DELETE = "QUOTA.TARIFF.DELETE"; + public static final String EVENT_QUOTA_TARIFF_UPDATE = "QUOTA.TARIFF.UPDATE"; + static { // TODO: need a way to force author adding event types to declare the entity details as well, with out braking @@ -1118,6 +1124,11 @@ public class EventTypes { entityEventDetails.put(EVENT_IMAGE_STORE_DATA_MIGRATE, ImageStore.class); entityEventDetails.put(EVENT_LIVE_PATCH_SYSTEMVM, "SystemVMs"); + + // Quota + entityEventDetails.put(EVENT_QUOTA_TARIFF_CREATE, QuotaTariff.class); + entityEventDetails.put(EVENT_QUOTA_TARIFF_DELETE, QuotaTariff.class); + entityEventDetails.put(EVENT_QUOTA_TARIFF_UPDATE, QuotaTariff.class); } public static String getEntityForEvent(String eventName) { diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java b/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java index 0a7ece7b7d8..1549167bc39 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiCommandResourceType.java @@ -77,7 +77,8 @@ public enum ApiCommandResourceType { Pod(com.cloud.dc.Pod.class), VmSnapshot(com.cloud.vm.snapshot.VMSnapshot.class), Role(org.apache.cloudstack.acl.Role.class), - VpnCustomerGateway(com.cloud.network.Site2SiteCustomerGateway.class); + VpnCustomerGateway(com.cloud.network.Site2SiteCustomerGateway.class), + QuotaTariff(org.apache.cloudstack.quota.QuotaTariff.class); private final Class clazz; diff --git a/api/src/main/java/org/apache/cloudstack/quota/QuotaTariff.java b/api/src/main/java/org/apache/cloudstack/quota/QuotaTariff.java new file mode 100644 index 00000000000..7de66a168f9 --- /dev/null +++ b/api/src/main/java/org/apache/cloudstack/quota/QuotaTariff.java @@ -0,0 +1,25 @@ +// 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 +// 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 org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +public interface QuotaTariff extends InternalIdentity, Identity { + +} diff --git a/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java b/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java index 1ab2c196ff8..4fe86b4d950 100644 --- a/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java +++ b/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java @@ -1461,9 +1461,9 @@ public abstract class GenericDaoBase extends Compone } else { _idField.set(entity, id); } - } else { - id = (ID)_idField.get(entity); } + + id = (ID)_idField.get(entity); } } catch (final IllegalAccessException e) { throw new CloudRuntimeException("Yikes! ", e); diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaTariffDaoImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaTariffDaoImpl.java index 470c84ac4e1..f73a7447d3e 100644 --- a/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaTariffDaoImpl.java +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/QuotaTariffDaoImpl.java @@ -231,4 +231,14 @@ public class QuotaTariffDaoImpl extends GenericDaoBase impl return quotaTariffs.get(0); } + + @Override + public QuotaTariffVO findByIdIncludingRemoved(Long id) { + return Transaction.execute(TransactionLegacy.USAGE_DB, (TransactionCallback) status -> super.findByIdIncludingRemoved(id)); + } + + @Override + public QuotaTariffVO findByUuidIncludingRemoved(String uuid) { + return Transaction.execute(TransactionLegacy.USAGE_DB, (TransactionCallback) status -> super.findByUuidIncludingRemoved(uuid)); + } } diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaTariffVO.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaTariffVO.java index 7bc2870e36a..d7721d88cbb 100644 --- a/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaTariffVO.java +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/vo/QuotaTariffVO.java @@ -16,7 +16,7 @@ //under the License. package org.apache.cloudstack.quota.vo; -import org.apache.cloudstack.api.InternalIdentity; +import org.apache.cloudstack.quota.QuotaTariff; import org.apache.cloudstack.quota.constant.QuotaTypes; import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils; @@ -37,7 +37,7 @@ import java.util.UUID; @Entity @Table(name = "quota_tariff") -public class QuotaTariffVO implements InternalIdentity { +public class QuotaTariffVO implements QuotaTariff { private static final long serialVersionUID = -7117933766387653203L; @Id @@ -240,6 +240,7 @@ public class QuotaTariffVO implements InternalIdentity { return description; } + @Override public String getUuid() { return uuid; } diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffCreateCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffCreateCmd.java index 2bbdb57fa7e..ea2edc3506d 100644 --- a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffCreateCmd.java +++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffCreateCmd.java @@ -20,6 +20,7 @@ import com.cloud.user.Account; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiCommandResourceType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.BaseCmd; @@ -27,6 +28,7 @@ import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.QuotaResponseBuilder; import org.apache.cloudstack.api.response.QuotaTariffResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.quota.vo.QuotaTariffVO; import org.apache.log4j.Logger; @@ -70,6 +72,7 @@ public class QuotaTariffCreateCmd extends BaseCmd { @Override public void execute() { + CallContext.current().setEventDetails(String.format("Tariff: %s, description: %s, value: %s", getName(), getDescription(), getValue())); QuotaTariffVO result = responseBuilder.createQuotaTariff(this); if (result == null) { @@ -134,4 +137,8 @@ public class QuotaTariffCreateCmd extends BaseCmd { this.endDate = endDate; } + @Override + public ApiCommandResourceType getApiResourceType() { + return ApiCommandResourceType.QuotaTariff; + } } diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffDeleteCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffDeleteCmd.java index 6fd46dc487e..6c2aa5866d7 100644 --- a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffDeleteCmd.java +++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffDeleteCmd.java @@ -21,12 +21,14 @@ import com.cloud.user.Account; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiArgValidator; +import org.apache.cloudstack.api.ApiCommandResourceType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.QuotaResponseBuilder; import org.apache.cloudstack.api.response.QuotaTariffResponse; import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.log4j.Logger; import javax.inject.Inject; @@ -49,6 +51,7 @@ public class QuotaTariffDeleteCmd extends BaseCmd { @Override public void execute() { + CallContext.current().setEventDetails(String.format("Tariff id: %s", getId())); boolean result = responseBuilder.deleteQuotaTariff(getId()); SuccessResponse response = new SuccessResponse(getCommandName()); response.setSuccess(result); @@ -60,4 +63,8 @@ public class QuotaTariffDeleteCmd extends BaseCmd { return Account.ACCOUNT_ID_SYSTEM; } + @Override + public ApiCommandResourceType getApiResourceType() { + return ApiCommandResourceType.QuotaTariff; + } } diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffUpdateCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffUpdateCmd.java index e2aad3a86f3..0bec1a63dcb 100644 --- a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffUpdateCmd.java +++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaTariffUpdateCmd.java @@ -20,6 +20,7 @@ import com.cloud.user.Account; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiCommandResourceType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; import org.apache.cloudstack.api.BaseCmd; @@ -27,6 +28,7 @@ import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.QuotaResponseBuilder; import org.apache.cloudstack.api.response.QuotaTariffResponse; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.quota.vo.QuotaTariffVO; import org.apache.log4j.Logger; @@ -111,6 +113,7 @@ public class QuotaTariffUpdateCmd extends BaseCmd { @Override public void execute() { + CallContext.current().setEventDetails(String.format("Tariff: %s, description: %s, value: %s", getName(), getDescription(), getValue())); final QuotaTariffVO result = _responseBuilder.updateQuotaTariffPlan(this); if (result == null) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update quota tariff plan"); @@ -125,4 +128,8 @@ public class QuotaTariffUpdateCmd extends BaseCmd { return Account.ACCOUNT_ID_SYSTEM; } + @Override + public ApiCommandResourceType getApiResourceType() { + return ApiCommandResourceType.QuotaTariff; + } } diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java index 32b49a72ae4..d7171499b7c 100644 --- a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java +++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java @@ -43,6 +43,7 @@ import org.apache.cloudstack.api.command.QuotaStatementCmd; import org.apache.cloudstack.api.command.QuotaTariffCreateCmd; import org.apache.cloudstack.api.command.QuotaTariffListCmd; import org.apache.cloudstack.api.command.QuotaTariffUpdateCmd; +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.quota.QuotaManager; import org.apache.cloudstack.quota.QuotaService; import org.apache.cloudstack.quota.QuotaStatement; @@ -75,6 +76,8 @@ import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; import com.cloud.utils.Pair; import com.cloud.utils.db.Filter; +import com.cloud.event.ActionEvent; +import com.cloud.event.EventTypes; @Component public class QuotaResponseBuilderImpl implements QuotaResponseBuilder { @@ -380,6 +383,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder { } @Override + @ActionEvent(eventType = EventTypes.EVENT_QUOTA_TARIFF_UPDATE, eventDescription = "updating Quota Tariff") public QuotaTariffVO updateQuotaTariffPlan(QuotaTariffUpdateCmd cmd) { String name = cmd.getName(); Double value = cmd.getValue(); @@ -403,6 +407,9 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder { QuotaTariffVO newQuotaTariff = persistNewQuotaTariff(currentQuotaTariff, name, 0, currentQuotaTariffStartDate, cmd.getEntityOwnerId(), endDate, value, description, activationRule); _quotaTariffDao.updateQuotaTariff(currentQuotaTariff); + + CallContext.current().setEventResourceId(newQuotaTariff.getId()); + return newQuotaTariff; } @@ -619,6 +626,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder { } @Override + @ActionEvent(eventType = EventTypes.EVENT_QUOTA_TARIFF_CREATE, eventDescription = "creating Quota Tariff") public QuotaTariffVO createQuotaTariff(QuotaTariffCreateCmd cmd) { String name = cmd.getName(); int usageType = cmd.getUsageType(); @@ -640,9 +648,14 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder { throw new InvalidParameterValueException(String.format("The quota tariff's start date [%s] cannot be less than now [%s]", startDate, now)); } - return persistNewQuotaTariff(null, name, usageType, startDate, cmd.getEntityOwnerId(), endDate, value, description, activationRule); + QuotaTariffVO newQuotaTariff = persistNewQuotaTariff(null, name, usageType, startDate, cmd.getEntityOwnerId(), endDate, value, description, activationRule); + + CallContext.current().setEventResourceId(newQuotaTariff.getId()); + + return newQuotaTariff; } + @ActionEvent(eventType = EventTypes.EVENT_QUOTA_TARIFF_DELETE, eventDescription = "removing Quota Tariff") public boolean deleteQuotaTariff(String quotaTariffUuid) { QuotaTariffVO quotaTariff = _quotaTariffDao.findByUuid(quotaTariffUuid); @@ -651,6 +664,9 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder { } quotaTariff.setRemoved(_quotaService.computeAdjustedTime(new Date())); + + CallContext.current().setEventResourceId(quotaTariff.getId()); + return _quotaTariffDao.updateQuotaTariff(quotaTariff); } } diff --git a/ui/src/components/view/SearchView.vue b/ui/src/components/view/SearchView.vue index 190db440fd1..1a3642dd452 100644 --- a/ui/src/components/view/SearchView.vue +++ b/ui/src/components/view/SearchView.vue @@ -339,7 +339,8 @@ export default { { value: 'Template' }, { value: 'User' }, { value: 'VirtualMachine' }, - { value: 'Volume' } + { value: 'Volume' }, + { value: 'QuotaTariff' } ] this.fields[resourceTypeIndex].loading = false } diff --git a/ui/src/components/widgets/ResourceLabel.vue b/ui/src/components/widgets/ResourceLabel.vue index c200c6a6655..6e44ce54a5d 100644 --- a/ui/src/components/widgets/ResourceLabel.vue +++ b/ui/src/components/widgets/ResourceLabel.vue @@ -58,11 +58,11 @@ export default { created () { if (this.resourceType) { var routePrefix = this.$getRouteFromResourceType(this.resourceType) - if (routePrefix && this.resourceId) { + if (routePrefix && this.resourceId && this.resourceType !== 'QuotaTariff') { this.resourceRoute = '/' + routePrefix + '/' + this.resourceId } this.resourceIcon = this.$getIconFromResourceType(this.resourceType) - this.resourceIconTooltip = this.$t('label.' + this.resourceType.toString().toLowerCase()) + this.resourceIconTooltip = this.$t('label.' + this.resourceType.toString().match(/[A-Z][a-z]*/g).join('.').toLowerCase()) } } } diff --git a/ui/src/utils/plugins.js b/ui/src/utils/plugins.js index 7223f050368..be6276dbd0c 100644 --- a/ui/src/utils/plugins.js +++ b/ui/src/utils/plugins.js @@ -417,6 +417,7 @@ export const resourceTypePlugin = { case 'AffinityGroup': case 'VpnCustomerGateway': case 'AutoScaleVmGroup': + case 'QuotaTariff': return resourceType.toLowerCase() } return ''