From 10b04ad4b9adb65ddb247abee00b830e7a8479ca Mon Sep 17 00:00:00 2001 From: Bryan Lima Date: Thu, 21 Mar 2024 10:21:22 -0300 Subject: [PATCH 01/13] Add network billing --- .../main/java/com/cloud/event/EventTypes.java | 4 + .../apache/cloudstack/usage/UsageTypes.java | 2 + .../orchestration/NetworkOrchestrator.java | 6 + .../java/com/cloud/usage/UsageNetworksVO.java | 141 ++++++++++++++++++ .../main/java/com/cloud/usage/UsageVO.java | 11 ++ .../com/cloud/usage/dao/UsageNetworksDao.java | 31 ++++ .../cloud/usage/dao/UsageNetworksDaoImpl.java | 134 +++++++++++++++++ ...s-between-management-and-usage-context.xml | 1 + ...spring-engine-schema-core-daos-context.xml | 1 + .../META-INF/db/schema-41720to41800.sql | 16 ++ .../presetvariables/PresetVariableHelper.java | 22 +++ .../activationrule/presetvariables/Value.java | 10 ++ .../cloudstack/quota/constant/QuotaTypes.java | 1 + .../cloudstack/quota/dao/NetworkDao.java | 23 +++ .../cloudstack/quota/dao/NetworkDaoImpl.java | 27 ++++ .../PresetVariableHelperTest.java | 1 + .../presetvariables/ValueTest.java | 8 + .../com/cloud/network/NetworkServiceImpl.java | 12 +- .../com/cloud/usage/UsageManagerImpl.java | 26 ++++ .../usage/parser/NetworksUsageParser.java | 95 ++++++++++++ 20 files changed, 570 insertions(+), 2 deletions(-) create mode 100644 engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java create mode 100644 engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDao.java create mode 100644 engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java create mode 100644 framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDao.java create mode 100644 framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDaoImpl.java create mode 100644 usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java diff --git a/api/src/main/java/com/cloud/event/EventTypes.java b/api/src/main/java/com/cloud/event/EventTypes.java index d385fa9ed07f..c8008ed2fd98 100644 --- a/api/src/main/java/com/cloud/event/EventTypes.java +++ b/api/src/main/java/com/cloud/event/EventTypes.java @@ -1191,6 +1191,10 @@ public class EventTypes { entityEventDetails.put(EVENT_QUOTA_TARIFF_UPDATE, QuotaTariff.class); } + public static boolean isNetworkEvent(String eventType) { + return EVENT_NETWORK_CREATE.equals(eventType) || EVENT_NETWORK_DELETE.equals(eventType) || + EVENT_NETWORK_UPDATE.equals(eventType); + } public static String getEntityForEvent(String eventName) { Object entityClass = entityEventDetails.get(eventName); if (entityClass == null) { diff --git a/api/src/main/java/org/apache/cloudstack/usage/UsageTypes.java b/api/src/main/java/org/apache/cloudstack/usage/UsageTypes.java index 5e0f03ff5830..633c497d78d5 100644 --- a/api/src/main/java/org/apache/cloudstack/usage/UsageTypes.java +++ b/api/src/main/java/org/apache/cloudstack/usage/UsageTypes.java @@ -46,6 +46,7 @@ public class UsageTypes { public static final int VM_SNAPSHOT_ON_PRIMARY = 27; public static final int BACKUP = 28; public static final int BUCKET = 29; + public static final int NETWORK = 30; public static List listUsageTypes() { List responseList = new ArrayList(); @@ -72,6 +73,7 @@ public static List listUsageTypes() { responseList.add(new UsageTypeResponse(VM_SNAPSHOT_ON_PRIMARY, "VM Snapshot on primary storage usage")); responseList.add(new UsageTypeResponse(BACKUP, "Backup storage usage")); responseList.add(new UsageTypeResponse(BUCKET, "Bucket storage usage")); + responseList.add(new UsageTypeResponse(NETWORK, "Network usage")); return responseList; } } diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 57f6f99bf2a2..c49a0fd09b13 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -1409,6 +1409,8 @@ public Pair implementNetwork(final long networkId, final if (isNetworkImplemented(network)) { s_logger.debug("Network id=" + networkId + " is already implemented"); implemented.set(guru, network); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_UPDATE, network.getAccountId(), network.getDataCenterId(), network.getId(), + network.getName(), network.getNetworkOfferingId(), null, network.getState().name(), Network.class.getName(), network.getUuid(), true); return implemented; } @@ -1469,6 +1471,8 @@ public Pair implementNetwork(final long networkId, final network.setRestartRequired(false); _networksDao.update(network.getId(), network); implemented.set(guru, network); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_CREATE, network.getAccountId(), network.getDataCenterId(), network.getId(), + network.getName(), network.getNetworkOfferingId(), null, null, null, network.getState().name(), network.getUuid()); return implemented; } catch (final NoTransitionException e) { s_logger.error(e.getMessage()); @@ -3344,6 +3348,8 @@ public void doInTransactionWithoutResult(final TransactionStatus status) { final Pair, Long> networkMsg = new Pair, Long>(Network.class, networkFinal.getId()); _messageBus.publish(_name, EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, PublishScope.LOCAL, networkMsg); } + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_DELETE, network.getAccountId(), network.getDataCenterId(), network.getId(), + network.getName(), network.getNetworkOfferingId(), null, null, null, Network.class.getName(), network.getUuid()); return true; } catch (final CloudRuntimeException e) { s_logger.error("Failed to delete network", e); diff --git a/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java new file mode 100644 index 000000000000..f5fd4eccb2a8 --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java @@ -0,0 +1,141 @@ +// 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 com.cloud.usage; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import org.apache.cloudstack.api.InternalIdentity; + +import java.util.Date; + +@Entity +@Table(name = "usage_networks") +public class UsageNetworksVO implements InternalIdentity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "network_id") + private long networkId; + + @Column(name = "network_offering_id") + private long networkOfferingId; + + @Column(name = "zone_id") + private long zoneId; + + @Column(name = "account_id") + private long accountId; + + @Column(name = "domain_id") + private long domainId; + + @Column(name = "state") + private String state; + + @Column(name = "created") + @Temporal(value = TemporalType.TIMESTAMP) + private Date created = null; + + @Column(name = "removed") + @Temporal(value = TemporalType.TIMESTAMP) + private Date removed = null; + + protected UsageNetworksVO(){} + + public UsageNetworksVO(long id, long networkId, long networkOfferingId, long zoneId, long accountId, long domainId, String state, Date created, Date removed) { + this.id = id; + this.networkId = networkId; + this.networkOfferingId = networkOfferingId; + this.zoneId = zoneId; + this.domainId = domainId; + this.accountId = accountId; + this.state = state; + this.created = created; + this.removed = removed; + } + public UsageNetworksVO(long networkId, long networkOfferingId, long zoneId, long accountId, long domainId, String state, Date created, Date removed) { + this.networkId = networkId; + this.networkOfferingId = networkOfferingId; + this.zoneId = zoneId; + this.domainId = domainId; + this.accountId = accountId; + this.state = state; + this.created = created; + this.removed = removed; + } + + @Override + public long getId() { + return id; + } + + public long getZoneId() { + return zoneId; + } + + public long getAccountId() { + return accountId; + } + + public long getDomainId() { + return domainId; + } + + public long getNetworkId() { + return networkId; + } + + public void setNetworkId(long networkId) { + this.networkId = networkId; + } + + public long getNetworkOfferingId() { + return networkOfferingId; + } + + public void setNetworkOfferingId(long networkOfferingId) { + this.networkOfferingId = networkOfferingId; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public Date getCreated() { + return created; + } + + public Date getRemoved() { + return removed; + } + + public void setRemoved(Date removed) { + this.removed = removed; + } +} \ No newline at end of file diff --git a/engine/schema/src/main/java/com/cloud/usage/UsageVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageVO.java index 10b295f593cf..054ec52e2812 100644 --- a/engine/schema/src/main/java/com/cloud/usage/UsageVO.java +++ b/engine/schema/src/main/java/com/cloud/usage/UsageVO.java @@ -110,6 +110,9 @@ public class UsageVO implements Usage, InternalIdentity { @Column(name = "is_hidden") private boolean isHidden = false; + @Column(name = "state") + private String state; + public Integer getQuotaCalculated() { return quotaCalculated; } @@ -398,6 +401,14 @@ public void setHidden(boolean hidden) { this.isHidden = hidden; } + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + @Override public String toString() { return ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "usageId", "usageType", "startDate", "endDate"); diff --git a/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDao.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDao.java new file mode 100644 index 000000000000..9be4c49b55e0 --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDao.java @@ -0,0 +1,31 @@ +// 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 com.cloud.usage.dao; + +import com.cloud.usage.UsageNetworksVO; +import com.cloud.utils.db.GenericDao; + +import java.util.Date; +import java.util.List; + +public interface UsageNetworksDao extends GenericDao { + void update(long networkId, long newNetworkOffering, String state); + + void remove(long networkId, Date removed); + + List getUsageRecords(Long accountId, Date startDate, Date endDate); +} diff --git a/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java new file mode 100644 index 000000000000..b52574df92cf --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java @@ -0,0 +1,134 @@ +// 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 com.cloud.usage.dao; + +import com.cloud.network.Network; +import com.cloud.usage.UsageNetworksVO; +import com.cloud.utils.DateUtil; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.TransactionLegacy; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +@Component +public class UsageNetworksDaoImpl extends GenericDaoBase implements UsageNetworksDao { + private static final Logger LOGGER = Logger.getLogger(UsageNetworksDaoImpl.class); + protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT id, network_id, network_offering_id, zone_id, account_id, domain_id, state, created, removed FROM usage_networks WHERE " + + " account_id = ? AND ((removed IS NULL AND created <= ?) OR (created BETWEEN ? AND ?) OR (removed BETWEEN ? AND ?) " + + " OR ((created <= ?) AND (removed >= ?)))"; + + + @Override + public void update(long networkId, long newNetworkOffering, String state) { + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); + try { + SearchCriteria sc = this.createSearchCriteria(); + sc.addAnd("networkId", SearchCriteria.Op.EQ, networkId); + sc.addAnd("removed", SearchCriteria.Op.NULL); + UsageNetworksVO vo = findOneBy(sc); + if (vo != null) { + vo.setNetworkOfferingId(newNetworkOffering); + vo.setState(state); + update(vo.getId(), vo); + } + } catch (final Exception e) { + txn.rollback(); + LOGGER.error(String.format("Error updating usage of network due to [%s].", e.getMessage()), e); + } finally { + txn.close(); + } + } + + @Override + public void remove(long networkId, Date removed) { + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); + try { + SearchCriteria sc = this.createSearchCriteria(); + sc.addAnd("networkId", SearchCriteria.Op.EQ, networkId); + sc.addAnd("removed", SearchCriteria.Op.NULL); + UsageNetworksVO vo = findOneBy(sc); + if (vo != null) { + vo.setRemoved(removed); + vo.setState(Network.State.Destroy.name()); + update(vo.getId(), vo); + } + } catch (final Exception e) { + txn.rollback(); + LOGGER.error(String.format("Error updating usage of network due to [%s].", e.getMessage()), e); + } finally { + txn.close(); + } + } + + @Override + public List getUsageRecords(Long accountId, Date startDate, Date endDate) { + List usageRecords = new ArrayList<>(); + TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); + PreparedStatement pstmt; + try { + int i = 1; + pstmt = txn.prepareAutoCloseStatement(GET_USAGE_RECORDS_BY_ACCOUNT); + pstmt.setLong(i++, accountId); + + pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate)); + pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate)); + pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate)); + pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate)); + pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate)); + pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), startDate)); + pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate)); + + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + long id = rs.getLong(1); + long networkId = rs.getLong(2); + long networkOfferingId = rs.getLong(3); + long zoneId = rs.getLong(4); + long acctId = rs.getLong(5); + long domId = rs.getLong(6); + String stateTS = rs.getString(7); + Date createdDate = null; + Date removedDate = null; + String createdTS = rs.getString(8); + String removedTS = rs.getString(9); + + if (createdTS != null) { + createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS); + } + if (removedTS != null) { + removedDate = DateUtil.parseDateString(s_gmtTimeZone, removedTS); + } + usageRecords.add(new UsageNetworksVO(id, networkId, networkOfferingId, zoneId, acctId, domId, stateTS, createdDate, removedDate)); + } + } catch (Exception e) { + txn.rollback(); + LOGGER.warn("Error getting networks usage records", e); + } finally { + txn.close(); + } + + return usageRecords; + } +} \ No newline at end of file diff --git a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-common-daos-between-management-and-usage-context.xml b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-common-daos-between-management-and-usage-context.xml index 0c46c5ff9341..81f9bf50a2cb 100644 --- a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-common-daos-between-management-and-usage-context.xml +++ b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-common-daos-between-management-and-usage-context.xml @@ -67,6 +67,7 @@ + diff --git a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index 5d9583831610..bd6c10dc8284 100644 --- a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -197,6 +197,7 @@ + diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41720to41800.sql b/engine/schema/src/main/resources/META-INF/db/schema-41720to41800.sql index c51d5a43045e..754b7003f5d1 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41720to41800.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41720to41800.sql @@ -1571,3 +1571,19 @@ WHERE usage_type = 24 AND usage_display like '% io write'; CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.guest_os', 'display', 'tinyint(1) DEFAULT ''1'' COMMENT ''should this guest_os be shown to the end user'' '); + +-- PR #7236 - [Usage] Create network billing +CREATE TABLE IF NOT EXISTS `cloud_usage`.`usage_networks` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `network_offering_id` bigint(20) unsigned NOT NULL, + `zone_id` bigint(20) unsigned NOT NULL, + `network_id` bigint(20) unsigned NOT NULL, + `account_id` bigint(20) unsigned NOT NULL, + `domain_id` bigint(20) unsigned NOT NULL, + `state` varchar(100) DEFAULT NULL, + `removed` datetime DEFAULT NULL, + `created` datetime NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB CHARSET=utf8; + +CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.cloud_usage', 'state', 'VARCHAR(100) DEFAULT NULL'); diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelper.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelper.java index 9723d3e5899f..2e9afd2abfde 100644 --- a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelper.java +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelper.java @@ -26,6 +26,7 @@ import java.util.stream.Collectors; import com.cloud.host.HostTagVO; +import com.cloud.network.dao.NetworkVO; import javax.inject.Inject; import com.cloud.hypervisor.Hypervisor; @@ -36,6 +37,7 @@ import org.apache.cloudstack.backup.dao.BackupOfferingDao; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.quota.constant.QuotaTypes; +import org.apache.cloudstack.quota.dao.NetworkDao; import org.apache.cloudstack.quota.dao.VmTemplateDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; @@ -170,6 +172,9 @@ public class PresetVariableHelper { @Inject BackupOfferingDao backupOfferingDao; + @Inject + NetworkDao networkDao; + protected boolean backupSnapshotAfterTakingSnapshot = SnapshotInfo.BackupSnapshotAfterTakingSnapshot.value(); private List runningAndAllocatedVmUsageTypes = Arrays.asList(UsageTypes.RUNNING_VM, UsageTypes.ALLOCATED_VM); @@ -273,6 +278,7 @@ protected Value getPresetVariableValue(UsageVO usageRecord) { loadPresetVariableValueForNetworkOffering(usageRecord, value); loadPresetVariableValueForVmSnapshot(usageRecord, value); loadPresetVariableValueForBackup(usageRecord, value); + loadPresetVariableValueForNetwork(usageRecord, value); return value; } @@ -689,6 +695,22 @@ protected BackupOffering getPresetVariableValueBackupOffering(Long offeringId) { return backupOffering; } + protected void loadPresetVariableValueForNetwork(UsageVO usageRecord, Value value) { + int usageType = usageRecord.getUsageType(); + if (usageType != QuotaTypes.NETWORK) { + logNotLoadingMessageInTrace("Network", usageType); + return; + } + + Long networkId = usageRecord.getUsageId(); + NetworkVO network = networkDao.findByIdIncludingRemoved(networkId); + validateIfObjectIsNull(network, networkId, "Network"); + + value.setId(network.getUuid()); + value.setName(network.getName()); + value.setState(usageRecord.getState()); + } + /** * Throws a {@link CloudRuntimeException} if the object is null; */ diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/Value.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/Value.java index f3accd83be84..a1dc7b3c1bb0 100644 --- a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/Value.java +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/Value.java @@ -43,6 +43,7 @@ public class Value extends GenericPresetVariable { private BackupOffering backupOffering; private String hypervisorType; private String volumeFormat; + private String state; public Host getHost() { return host; @@ -205,4 +206,13 @@ public void setVolumeFormat(String volumeFormat) { public String getVolumeFormat() { return volumeFormat; } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + fieldNamesToIncludeInToString.add("state"); + } } diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/constant/QuotaTypes.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/constant/QuotaTypes.java index 6f19fa95f1bc..2d80ae51ef17 100644 --- a/framework/quota/src/main/java/org/apache/cloudstack/quota/constant/QuotaTypes.java +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/constant/QuotaTypes.java @@ -56,6 +56,7 @@ public class QuotaTypes extends UsageTypes { quotaTypeList.put(VM_SNAPSHOT_ON_PRIMARY, new QuotaTypes(VM_SNAPSHOT_ON_PRIMARY, "VM_SNAPSHOT_ON_PRIMARY", UsageUnitTypes.GB_MONTH.toString(), "VM Snapshot primary storage usage")); quotaTypeList.put(BACKUP, new QuotaTypes(BACKUP, "BACKUP", UsageUnitTypes.GB_MONTH.toString(), "Backup storage usage")); quotaTypeList.put(BUCKET, new QuotaTypes(BUCKET, "BUCKET", UsageUnitTypes.GB_MONTH.toString(), "Object Store bucket usage")); + quotaTypeList.put(NETWORK, new QuotaTypes(NETWORK, "NETWORK", UsageUnitTypes.GB_MONTH.toString(), "Network usage")); quotaTypeMap = Collections.unmodifiableMap(quotaTypeList); } diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDao.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDao.java new file mode 100644 index 000000000000..3fbea7497015 --- /dev/null +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDao.java @@ -0,0 +1,23 @@ +// 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 com.cloud.network.dao.NetworkVO; +import com.cloud.utils.db.GenericDao; + +public interface NetworkDao extends GenericDao { +} \ No newline at end of file diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDaoImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDaoImpl.java new file mode 100644 index 000000000000..fdb3d006d2bd --- /dev/null +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDaoImpl.java @@ -0,0 +1,27 @@ +// 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 com.cloud.network.dao.NetworkVO; +import com.cloud.utils.db.GenericDaoBase; + +/** + * This class was created to specifically use in {@link org.apache.cloudstack.quota.activationrule.presetvariables.PresetVariableHelper}.

+ * It was not possible to inject {@link com.cloud.network.dao.NetworkDao} due to its complex injection hierarchy. + */ +public class NetworkDaoImpl extends GenericDaoBase implements NetworkDao { +} \ No newline at end of file diff --git a/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelperTest.java b/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelperTest.java index b973d1145c30..49ba7636c469 100644 --- a/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelperTest.java +++ b/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelperTest.java @@ -471,6 +471,7 @@ public void getPresetVariableValueTestSetFieldsAndReturnObject() { Mockito.doNothing().when(presetVariableHelperSpy).loadPresetVariableValueForNetworkOffering(Mockito.any(UsageVO.class), Mockito.any(Value.class)); Mockito.doNothing().when(presetVariableHelperSpy).loadPresetVariableValueForVmSnapshot(Mockito.any(UsageVO.class), Mockito.any(Value.class)); Mockito.doNothing().when(presetVariableHelperSpy).loadPresetVariableValueForBackup(Mockito.any(UsageVO.class), Mockito.any(Value.class)); + Mockito.doNothing().when(presetVariableHelperSpy).loadPresetVariableValueForNetwork(Mockito.any(UsageVO.class), Mockito.any(Value.class)); Value result = presetVariableHelperSpy.getPresetVariableValue(usageVoMock); diff --git a/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/ValueTest.java b/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/ValueTest.java index 9e65de754c8e..4d0162b33c98 100644 --- a/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/ValueTest.java +++ b/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/ValueTest.java @@ -150,4 +150,12 @@ public void setVolumeFormatTestAddFieldVolumeFormatToCollection() { variable.setVolumeFormat(null); Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("volumeFormat")); } + + @Test + public void setStateTestAddFieldStateToCollection() { + Value variable = new Value(); + variable.setState(null); + Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("state")); + } + } diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java index 18f98e6f99f1..b98e3213785a 100644 --- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java @@ -1977,7 +1977,12 @@ private Network implementedNetworkInCreation(final Account caller, final DataCen if (implementedNetwork == null || implementedNetwork.first() == null) { s_logger.warn("Failed to provision the network " + network); } - return implementedNetwork.second(); + Network implemented = implementedNetwork.second(); + if (implemented != null) { + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_CREATE, implemented.getAccountId(), implemented.getDataCenterId(), implemented.getId(), + implemented.getName(), implemented.getNetworkOfferingId(), null, null, null, Network.class.getName(), implemented.getUuid()); + } + return implemented; } catch (ResourceUnavailableException ex) { s_logger.warn("Failed to implement persistent guest network " + network + "due to ", ex); CloudRuntimeException e = new CloudRuntimeException("Failed to implement persistent guest network"); @@ -3374,7 +3379,10 @@ public void doInTransactionWithoutResult(TransactionStatus status) { } } } - return getNetwork(network.getId()); + Network updatedNetwork = getNetwork(network.getId()); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_UPDATE, updatedNetwork.getAccountId(), updatedNetwork.getDataCenterId(), updatedNetwork.getId(), + updatedNetwork.getName(), updatedNetwork.getNetworkOfferingId(), null, updatedNetwork.getState().name(), Network.class.getName(), updatedNetwork.getUuid(), true); + return updatedNetwork; } protected Pair validateMtuOnUpdate(NetworkVO network, Long zoneId, Integer publicMtu, Integer privateMtu) { diff --git a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java index a001ffe147c3..100f50192f0d 100644 --- a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java @@ -32,6 +32,9 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import com.cloud.network.Network; +import com.cloud.usage.dao.UsageNetworksDao; +import com.cloud.usage.parser.NetworksUsageParser; import javax.inject.Inject; import javax.naming.ConfigurationException; import javax.persistence.EntityExistsException; @@ -166,6 +169,8 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna private QuotaAlertManager _alertManager; @Inject private QuotaStatement _quotaStatement; + @Inject + private UsageNetworksDao usageNetworksDao; @Inject private BucketStatisticsDao _bucketStatisticsDao; @@ -1031,6 +1036,10 @@ private boolean parseHelperTables(AccountVO account, Date currentStartDate, Date s_logger.debug("Bucket usage successfully parsed? " + parsed + " (for account: " + account.getAccountName() + ", id: " + account.getId() + ")"); } } + parsed = NetworksUsageParser.parse(account, currentStartDate, currentEndDate); + if (!parsed) { + s_logger.debug(String.format("Networks usage not parsed for account [%s].", account)); + } return parsed; } @@ -1065,6 +1074,8 @@ private void createHelperRecord(UsageEventVO event) { createVmSnapshotOnPrimaryEvent(event); } else if (isBackupEvent(eventType)) { createBackupEvent(event); + } else if (EventTypes.isNetworkEvent(eventType)) { + handleNetworkEvent(event); } } catch (EntityExistsException e) { s_logger.warn(String.format("Failed to create usage event id: %d type: %s due to %s", event.getId(), eventType, e.getMessage()), e); @@ -2110,6 +2121,21 @@ private void createBackupEvent(final UsageEventVO event) { } } + private void handleNetworkEvent(UsageEventVO event) { + Account account = _accountDao.findByIdIncludingRemoved(event.getAccountId()); + long domainId = account.getDomainId(); + if (EventTypes.EVENT_NETWORK_DELETE.equals(event.getType())) { + usageNetworksDao.remove(event.getResourceId(), event.getCreateDate()); + } else if (EventTypes.EVENT_NETWORK_CREATE.equals(event.getType())) { + UsageNetworksVO usageNetworksVO = new UsageNetworksVO(event.getResourceId(), event.getOfferingId(), event.getZoneId(), event.getAccountId(), domainId, Network.State.Allocated.name(), event.getCreateDate(), null); + usageNetworksDao.persist(usageNetworksVO); + } else if (EventTypes.EVENT_NETWORK_UPDATE.equals(event.getType())) { + usageNetworksDao.update(event.getResourceId(), event.getOfferingId(), event.getResourceType()); + } else { + s_logger.error(String.format("Unknown event type [%s] in Networks event parser. Skipping it.", event.getType())); + } + } + private class Heartbeat extends ManagedContextRunnable { @Override protected void runInContext() { diff --git a/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java new file mode 100644 index 000000000000..68990ec11281 --- /dev/null +++ b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java @@ -0,0 +1,95 @@ +// 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 com.cloud.usage.parser; + + + +import com.cloud.usage.UsageNetworksVO; +import com.cloud.usage.UsageVO; +import com.cloud.usage.dao.UsageDao; +import com.cloud.usage.dao.UsageNetworksDao; +import com.cloud.user.AccountVO; +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import org.apache.cloudstack.usage.UsageTypes; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import java.text.DecimalFormat; +import java.util.Date; +import java.util.List; + +@Component +public class NetworksUsageParser { + private static final Logger LOGGER = Logger.getLogger(NetworksUsageParser.class.getName()); + + @Inject + private UsageNetworksDao networksDao; + @Inject + private UsageDao usageDao; + + private static UsageDao staticUsageDao; + private static UsageNetworksDao staticNetworksDao; + + @PostConstruct + void init() { + staticUsageDao = usageDao; + staticNetworksDao = networksDao; + } + + public static boolean parse(AccountVO account, Date startDate, Date endDate) { + LOGGER.debug(String.format("Parsing all networks usage events for account [%s].", account.getId())); + if ((endDate == null) || endDate.after(new Date())) { + endDate = new Date(); + } + + final List usageNetworksVO = staticNetworksDao.getUsageRecords(account.getId(), startDate, endDate); + if (usageNetworksVO == null || usageNetworksVO.isEmpty()) { + LOGGER.debug(String.format("Cannot find any VPC usage for account [%s] in period between [%s] and [%s].", account, startDate, endDate)); + return true; + } + + for (final UsageNetworksVO usageNetwork : usageNetworksVO) { + Long zoneId = usageNetwork.getZoneId(); + Date createdDate = usageNetwork.getCreated(); + Date removedDate = usageNetwork.getRemoved(); + if (createdDate.before(startDate)) { + createdDate = startDate; + } + + if (removedDate == null || removedDate.after(endDate)) { + removedDate = endDate; + } + + final long duration = (removedDate.getTime() - createdDate.getTime()) + 1; + final float usage = duration / 1000f / 60f / 60f; + DecimalFormat dFormat = new DecimalFormat("#.######"); + String usageDisplay = dFormat.format(usage); + + String description = String.format("Network usage for network ID: %d, network offering: %d", usageNetwork.getNetworkId(), usageNetwork.getNetworkOfferingId()); + UsageVO usageRecord = + new UsageVO(zoneId, account.getAccountId(), account.getDomainId(), description, usageDisplay + " Hrs", + UsageTypes.NETWORK, (double) usage, null, null, usageNetwork.getNetworkOfferingId(), null, usageNetwork.getNetworkId(), + (long)0, null, startDate, endDate); + usageRecord.setState(usageNetwork.getState()); + staticUsageDao.persist(usageRecord); + } + + return true; + } + +} \ No newline at end of file From 82342afb502b87bc8e454fe80783d9d8f09ab736 Mon Sep 17 00:00:00 2001 From: Bryan Lima Date: Thu, 21 Mar 2024 10:24:06 -0300 Subject: [PATCH 02/13] Address Daniel and Joao reviews --- .../java/org/apache/cloudstack/quota/constant/QuotaTypes.java | 2 +- .../main/java/com/cloud/usage/parser/NetworksUsageParser.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/constant/QuotaTypes.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/constant/QuotaTypes.java index 2d80ae51ef17..2a33cd99116d 100644 --- a/framework/quota/src/main/java/org/apache/cloudstack/quota/constant/QuotaTypes.java +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/constant/QuotaTypes.java @@ -56,7 +56,7 @@ public class QuotaTypes extends UsageTypes { quotaTypeList.put(VM_SNAPSHOT_ON_PRIMARY, new QuotaTypes(VM_SNAPSHOT_ON_PRIMARY, "VM_SNAPSHOT_ON_PRIMARY", UsageUnitTypes.GB_MONTH.toString(), "VM Snapshot primary storage usage")); quotaTypeList.put(BACKUP, new QuotaTypes(BACKUP, "BACKUP", UsageUnitTypes.GB_MONTH.toString(), "Backup storage usage")); quotaTypeList.put(BUCKET, new QuotaTypes(BUCKET, "BUCKET", UsageUnitTypes.GB_MONTH.toString(), "Object Store bucket usage")); - quotaTypeList.put(NETWORK, new QuotaTypes(NETWORK, "NETWORK", UsageUnitTypes.GB_MONTH.toString(), "Network usage")); + quotaTypeList.put(NETWORK, new QuotaTypes(NETWORK, "NETWORK", UsageUnitTypes.COMPUTE_MONTH.toString(), "Network usage")); quotaTypeMap = Collections.unmodifiableMap(quotaTypeList); } diff --git a/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java index 68990ec11281..ea4ec2a0c6ec 100644 --- a/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java +++ b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java @@ -59,7 +59,7 @@ public static boolean parse(AccountVO account, Date startDate, Date endDate) { final List usageNetworksVO = staticNetworksDao.getUsageRecords(account.getId(), startDate, endDate); if (usageNetworksVO == null || usageNetworksVO.isEmpty()) { - LOGGER.debug(String.format("Cannot find any VPC usage for account [%s] in period between [%s] and [%s].", account, startDate, endDate)); + LOGGER.debug(String.format("Could not find any network usage for account [%s], between [%s] and [%s].", account, startDate, endDate)); return true; } From 38575a3bcd23f4431096125dcaf40fcf1af5d8c1 Mon Sep 17 00:00:00 2001 From: Bryan Lima Date: Thu, 21 Mar 2024 10:32:08 -0300 Subject: [PATCH 03/13] Fix update paths --- .../META-INF/db/schema-41720to41800.sql | 16 ---------------- .../META-INF/db/schema-41900to41910.sql | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41720to41800.sql b/engine/schema/src/main/resources/META-INF/db/schema-41720to41800.sql index 754b7003f5d1..c51d5a43045e 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41720to41800.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41720to41800.sql @@ -1571,19 +1571,3 @@ WHERE usage_type = 24 AND usage_display like '% io write'; CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.guest_os', 'display', 'tinyint(1) DEFAULT ''1'' COMMENT ''should this guest_os be shown to the end user'' '); - --- PR #7236 - [Usage] Create network billing -CREATE TABLE IF NOT EXISTS `cloud_usage`.`usage_networks` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `network_offering_id` bigint(20) unsigned NOT NULL, - `zone_id` bigint(20) unsigned NOT NULL, - `network_id` bigint(20) unsigned NOT NULL, - `account_id` bigint(20) unsigned NOT NULL, - `domain_id` bigint(20) unsigned NOT NULL, - `state` varchar(100) DEFAULT NULL, - `removed` datetime DEFAULT NULL, - `created` datetime NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB CHARSET=utf8; - -CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.cloud_usage', 'state', 'VARCHAR(100) DEFAULT NULL'); diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql b/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql index e704d61d70c1..e68b42d6b148 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql @@ -30,3 +30,21 @@ UPDATE cloud_usage.quota_tariff SET usage_unit = 'IOPS', updated_on = NOW() WHERE effective_on = '2010-05-04 00:00:00' AND name IN ('VM_DISK_IO_READ', 'VM_DISK_IO_WRITE'); + +CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.guest_os', 'display', 'tinyint(1) DEFAULT ''1'' COMMENT ''should this guest_os be shown to the end user'' '); + +-- PR #7236 - [Usage] Create network billing +CREATE TABLE IF NOT EXISTS `cloud_usage`.`usage_networks` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `network_offering_id` bigint(20) unsigned NOT NULL, + `zone_id` bigint(20) unsigned NOT NULL, + `network_id` bigint(20) unsigned NOT NULL, + `account_id` bigint(20) unsigned NOT NULL, + `domain_id` bigint(20) unsigned NOT NULL, + `state` varchar(100) DEFAULT NULL, + `removed` datetime DEFAULT NULL, + `created` datetime NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB CHARSET=utf8; + +CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.cloud_usage', 'state', 'VARCHAR(100) DEFAULT NULL'); \ No newline at end of file From 21385bc621dffa3c891835654336080f0271396c Mon Sep 17 00:00:00 2001 From: SadiJr Date: Mon, 18 Sep 2023 15:29:37 -0300 Subject: [PATCH 04/13] Fix end of files --- .../schema/src/main/java/com/cloud/usage/UsageNetworksVO.java | 2 +- .../src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java | 2 +- .../main/java/org/apache/cloudstack/quota/dao/NetworkDao.java | 2 +- .../java/org/apache/cloudstack/quota/dao/NetworkDaoImpl.java | 2 +- .../main/java/com/cloud/usage/parser/NetworksUsageParser.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java index f5fd4eccb2a8..014857eef0c9 100644 --- a/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java +++ b/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java @@ -138,4 +138,4 @@ public Date getRemoved() { public void setRemoved(Date removed) { this.removed = removed; } -} \ No newline at end of file +} diff --git a/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java index b52574df92cf..8829414f3f26 100644 --- a/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java @@ -131,4 +131,4 @@ public List getUsageRecords(Long accountId, Date startDate, Dat return usageRecords; } -} \ No newline at end of file +} diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDao.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDao.java index 3fbea7497015..57b1981e9982 100644 --- a/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDao.java +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDao.java @@ -20,4 +20,4 @@ import com.cloud.utils.db.GenericDao; public interface NetworkDao extends GenericDao { -} \ No newline at end of file +} diff --git a/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDaoImpl.java b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDaoImpl.java index fdb3d006d2bd..bc581238d51f 100644 --- a/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDaoImpl.java +++ b/framework/quota/src/main/java/org/apache/cloudstack/quota/dao/NetworkDaoImpl.java @@ -24,4 +24,4 @@ * It was not possible to inject {@link com.cloud.network.dao.NetworkDao} due to its complex injection hierarchy. */ public class NetworkDaoImpl extends GenericDaoBase implements NetworkDao { -} \ No newline at end of file +} diff --git a/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java index ea4ec2a0c6ec..47d04dd54dc1 100644 --- a/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java +++ b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java @@ -92,4 +92,4 @@ public static boolean parse(AccountVO account, Date startDate, Date endDate) { return true; } -} \ No newline at end of file +} From 4d2b465ec911c22f1b3bb7e64ff95593ea687991 Mon Sep 17 00:00:00 2001 From: Bryan Lima Date: Fri, 1 Mar 2024 10:35:09 -0300 Subject: [PATCH 05/13] Change logger to log4j2 apis --- .../java/com/cloud/usage/dao/UsageNetworksDaoImpl.java | 8 +++----- .../src/main/java/com/cloud/usage/UsageManagerImpl.java | 4 ++-- .../java/com/cloud/usage/parser/NetworksUsageParser.java | 9 +++++---- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java index 8829414f3f26..bc7d17cde22e 100644 --- a/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java @@ -22,7 +22,6 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.TransactionLegacy; -import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import java.sql.PreparedStatement; @@ -34,7 +33,6 @@ @Component public class UsageNetworksDaoImpl extends GenericDaoBase implements UsageNetworksDao { - private static final Logger LOGGER = Logger.getLogger(UsageNetworksDaoImpl.class); protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT id, network_id, network_offering_id, zone_id, account_id, domain_id, state, created, removed FROM usage_networks WHERE " + " account_id = ? AND ((removed IS NULL AND created <= ?) OR (created BETWEEN ? AND ?) OR (removed BETWEEN ? AND ?) " + " OR ((created <= ?) AND (removed >= ?)))"; @@ -55,7 +53,7 @@ public void update(long networkId, long newNetworkOffering, String state) { } } catch (final Exception e) { txn.rollback(); - LOGGER.error(String.format("Error updating usage of network due to [%s].", e.getMessage()), e); + logger.error("Error updating usage of network due to [{}].", e.getMessage(), e); } finally { txn.close(); } @@ -76,7 +74,7 @@ public void remove(long networkId, Date removed) { } } catch (final Exception e) { txn.rollback(); - LOGGER.error(String.format("Error updating usage of network due to [%s].", e.getMessage()), e); + logger.error("Error updating usage of network due to [{}].", e.getMessage(), e); } finally { txn.close(); } @@ -124,7 +122,7 @@ public List getUsageRecords(Long accountId, Date startDate, Dat } } catch (Exception e) { txn.rollback(); - LOGGER.warn("Error getting networks usage records", e); + logger.warn("Error getting networks usage records", e); } finally { txn.close(); } diff --git a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java index 100f50192f0d..34f60f16d60d 100644 --- a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java @@ -1038,7 +1038,7 @@ private boolean parseHelperTables(AccountVO account, Date currentStartDate, Date } parsed = NetworksUsageParser.parse(account, currentStartDate, currentEndDate); if (!parsed) { - s_logger.debug(String.format("Networks usage not parsed for account [%s].", account)); + logger.debug("Networks usage not parsed for account [{}].", account); } return parsed; } @@ -2132,7 +2132,7 @@ private void handleNetworkEvent(UsageEventVO event) { } else if (EventTypes.EVENT_NETWORK_UPDATE.equals(event.getType())) { usageNetworksDao.update(event.getResourceId(), event.getOfferingId(), event.getResourceType()); } else { - s_logger.error(String.format("Unknown event type [%s] in Networks event parser. Skipping it.", event.getType())); + logger.error("Unknown event type [{}] in Networks event parser. Skipping it.", event.getType()); } } diff --git a/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java index 47d04dd54dc1..b9a05774f96c 100644 --- a/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java +++ b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java @@ -26,7 +26,8 @@ import javax.annotation.PostConstruct; import javax.inject.Inject; import org.apache.cloudstack.usage.UsageTypes; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Component; import java.text.DecimalFormat; @@ -35,7 +36,7 @@ @Component public class NetworksUsageParser { - private static final Logger LOGGER = Logger.getLogger(NetworksUsageParser.class.getName()); + protected static Logger LOGGER = LogManager.getLogger(NetworksUsageParser.class); @Inject private UsageNetworksDao networksDao; @@ -52,14 +53,14 @@ void init() { } public static boolean parse(AccountVO account, Date startDate, Date endDate) { - LOGGER.debug(String.format("Parsing all networks usage events for account [%s].", account.getId())); + LOGGER.debug("Parsing all networks usage events for account [{}].", account.getId()); if ((endDate == null) || endDate.after(new Date())) { endDate = new Date(); } final List usageNetworksVO = staticNetworksDao.getUsageRecords(account.getId(), startDate, endDate); if (usageNetworksVO == null || usageNetworksVO.isEmpty()) { - LOGGER.debug(String.format("Could not find any network usage for account [%s], between [%s] and [%s].", account, startDate, endDate)); + LOGGER.debug("Could not find any network usage for account [{}], between [{}] and [{}].", account, startDate, endDate); return true; } From 9a39da05ab1e25efb748cc073ceb2fb67b370e3a Mon Sep 17 00:00:00 2001 From: Bryan Lima Date: Mon, 4 Mar 2024 14:29:38 -0300 Subject: [PATCH 06/13] Add logs --- .../com/cloud/usage/parser/NetworksUsageParser.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java index b9a05774f96c..661123fe0afb 100644 --- a/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java +++ b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java @@ -16,8 +16,7 @@ // under the License. package com.cloud.usage.parser; - - +import com.cloud.usage.UsageManagerImpl; import com.cloud.usage.UsageNetworksVO; import com.cloud.usage.UsageVO; import com.cloud.usage.dao.UsageDao; @@ -25,6 +24,8 @@ import com.cloud.user.AccountVO; import javax.annotation.PostConstruct; import javax.inject.Inject; + +import com.cloud.utils.DateUtil; import org.apache.cloudstack.usage.UsageTypes; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -81,6 +82,12 @@ public static boolean parse(AccountVO account, Date startDate, Date endDate) { DecimalFormat dFormat = new DecimalFormat("#.######"); String usageDisplay = dFormat.format(usage); + long networkId = usageNetwork.getNetworkId(); + long networkOfferingId = usageNetwork.getNetworkOfferingId(); + LOGGER.debug("Creating network usage record with id [{}], network offering [{}], usage [{}], startDate [{}], and endDate [{}], for account [{}].", + networkId, networkOfferingId, usageDisplay, DateUtil.displayDateInTimezone(UsageManagerImpl.getUsageAggregationTimeZone(), startDate), + DateUtil.displayDateInTimezone(UsageManagerImpl.getUsageAggregationTimeZone(), endDate), account.getId()); + String description = String.format("Network usage for network ID: %d, network offering: %d", usageNetwork.getNetworkId(), usageNetwork.getNetworkOfferingId()); UsageVO usageRecord = new UsageVO(zoneId, account.getAccountId(), account.getDomainId(), description, usageDisplay + " Hrs", From 5d3807958492376d995a59c5578650b37e265145 Mon Sep 17 00:00:00 2001 From: Bryan Lima Date: Thu, 21 Mar 2024 10:38:55 -0300 Subject: [PATCH 07/13] Remove leftover schema upgrade command --- .../src/main/resources/META-INF/db/schema-41900to41910.sql | 2 -- 1 file changed, 2 deletions(-) diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql b/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql index e68b42d6b148..3a418cfca20e 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql @@ -31,8 +31,6 @@ SET usage_unit = 'IOPS', updated_on = NOW() WHERE effective_on = '2010-05-04 00:00:00' AND name IN ('VM_DISK_IO_READ', 'VM_DISK_IO_WRITE'); -CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.guest_os', 'display', 'tinyint(1) DEFAULT ''1'' COMMENT ''should this guest_os be shown to the end user'' '); - -- PR #7236 - [Usage] Create network billing CREATE TABLE IF NOT EXISTS `cloud_usage`.`usage_networks` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, From 1067adcb873527c98e3e2167b41a886703ef1fee Mon Sep 17 00:00:00 2001 From: Bryan Lima Date: Thu, 21 Mar 2024 10:40:25 -0300 Subject: [PATCH 08/13] Add new line at EOF --- .../src/main/resources/META-INF/db/schema-41900to41910.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql b/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql index 3a418cfca20e..d442af35bd59 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql @@ -45,4 +45,4 @@ CREATE TABLE IF NOT EXISTS `cloud_usage`.`usage_networks` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB CHARSET=utf8; -CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.cloud_usage', 'state', 'VARCHAR(100) DEFAULT NULL'); \ No newline at end of file +CALL `cloud_usage`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.cloud_usage', 'state', 'VARCHAR(100) DEFAULT NULL'); From 2d9f0c43d6d9edb52016529156e94047fff4bd62 Mon Sep 17 00:00:00 2001 From: Bryan Lima Date: Tue, 26 Mar 2024 11:06:27 -0300 Subject: [PATCH 09/13] Fix logs --- .../cloud/usage/dao/UsageNetworksDaoImpl.java | 8 +++++--- .../java/com/cloud/usage/UsageManagerImpl.java | 4 ++-- .../cloud/usage/parser/NetworksUsageParser.java | 17 ++++++----------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java index bc7d17cde22e..8829414f3f26 100644 --- a/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/usage/dao/UsageNetworksDaoImpl.java @@ -22,6 +22,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.TransactionLegacy; +import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import java.sql.PreparedStatement; @@ -33,6 +34,7 @@ @Component public class UsageNetworksDaoImpl extends GenericDaoBase implements UsageNetworksDao { + private static final Logger LOGGER = Logger.getLogger(UsageNetworksDaoImpl.class); protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT id, network_id, network_offering_id, zone_id, account_id, domain_id, state, created, removed FROM usage_networks WHERE " + " account_id = ? AND ((removed IS NULL AND created <= ?) OR (created BETWEEN ? AND ?) OR (removed BETWEEN ? AND ?) " + " OR ((created <= ?) AND (removed >= ?)))"; @@ -53,7 +55,7 @@ public void update(long networkId, long newNetworkOffering, String state) { } } catch (final Exception e) { txn.rollback(); - logger.error("Error updating usage of network due to [{}].", e.getMessage(), e); + LOGGER.error(String.format("Error updating usage of network due to [%s].", e.getMessage()), e); } finally { txn.close(); } @@ -74,7 +76,7 @@ public void remove(long networkId, Date removed) { } } catch (final Exception e) { txn.rollback(); - logger.error("Error updating usage of network due to [{}].", e.getMessage(), e); + LOGGER.error(String.format("Error updating usage of network due to [%s].", e.getMessage()), e); } finally { txn.close(); } @@ -122,7 +124,7 @@ public List getUsageRecords(Long accountId, Date startDate, Dat } } catch (Exception e) { txn.rollback(); - logger.warn("Error getting networks usage records", e); + LOGGER.warn("Error getting networks usage records", e); } finally { txn.close(); } diff --git a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java index 34f60f16d60d..100f50192f0d 100644 --- a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java @@ -1038,7 +1038,7 @@ private boolean parseHelperTables(AccountVO account, Date currentStartDate, Date } parsed = NetworksUsageParser.parse(account, currentStartDate, currentEndDate); if (!parsed) { - logger.debug("Networks usage not parsed for account [{}].", account); + s_logger.debug(String.format("Networks usage not parsed for account [%s].", account)); } return parsed; } @@ -2132,7 +2132,7 @@ private void handleNetworkEvent(UsageEventVO event) { } else if (EventTypes.EVENT_NETWORK_UPDATE.equals(event.getType())) { usageNetworksDao.update(event.getResourceId(), event.getOfferingId(), event.getResourceType()); } else { - logger.error("Unknown event type [{}] in Networks event parser. Skipping it.", event.getType()); + s_logger.error(String.format("Unknown event type [%s] in Networks event parser. Skipping it.", event.getType())); } } diff --git a/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java index 661123fe0afb..b11fb47154fc 100644 --- a/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java +++ b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java @@ -16,7 +16,6 @@ // under the License. package com.cloud.usage.parser; -import com.cloud.usage.UsageManagerImpl; import com.cloud.usage.UsageNetworksVO; import com.cloud.usage.UsageVO; import com.cloud.usage.dao.UsageDao; @@ -25,10 +24,8 @@ import javax.annotation.PostConstruct; import javax.inject.Inject; -import com.cloud.utils.DateUtil; import org.apache.cloudstack.usage.UsageTypes; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import java.text.DecimalFormat; @@ -37,7 +34,7 @@ @Component public class NetworksUsageParser { - protected static Logger LOGGER = LogManager.getLogger(NetworksUsageParser.class); + private static final Logger LOGGER = Logger.getLogger(NetworksUsageParser.class.getName()); @Inject private UsageNetworksDao networksDao; @@ -54,14 +51,14 @@ void init() { } public static boolean parse(AccountVO account, Date startDate, Date endDate) { - LOGGER.debug("Parsing all networks usage events for account [{}].", account.getId()); + LOGGER.debug(String.format("Parsing all networks usage events for account [%s].", account.getId())); if ((endDate == null) || endDate.after(new Date())) { endDate = new Date(); } final List usageNetworksVO = staticNetworksDao.getUsageRecords(account.getId(), startDate, endDate); if (usageNetworksVO == null || usageNetworksVO.isEmpty()) { - LOGGER.debug("Could not find any network usage for account [{}], between [{}] and [{}].", account, startDate, endDate); + LOGGER.debug(String.format("Cannot find any VPC usage for account [%s] in period between [%s] and [%s].", account, startDate, endDate)); return true; } @@ -84,9 +81,8 @@ public static boolean parse(AccountVO account, Date startDate, Date endDate) { long networkId = usageNetwork.getNetworkId(); long networkOfferingId = usageNetwork.getNetworkOfferingId(); - LOGGER.debug("Creating network usage record with id [{}], network offering [{}], usage [{}], startDate [{}], and endDate [{}], for account [{}].", - networkId, networkOfferingId, usageDisplay, DateUtil.displayDateInTimezone(UsageManagerImpl.getUsageAggregationTimeZone(), startDate), - DateUtil.displayDateInTimezone(UsageManagerImpl.getUsageAggregationTimeZone(), endDate), account.getId()); + LOGGER.debug(String.format("Creating network usage record with id [%s], network offering [%s], usage [%s], startDate [%s], and endDate [%s], for account [%s].", + networkId, networkOfferingId, usageDisplay, startDate, endDate, account.getId())); String description = String.format("Network usage for network ID: %d, network offering: %d", usageNetwork.getNetworkId(), usageNetwork.getNetworkOfferingId()); UsageVO usageRecord = @@ -99,5 +95,4 @@ public static boolean parse(AccountVO account, Date startDate, Date endDate) { return true; } - } From 50545285be53c0f2c41f965f9ff1537618e4bbc0 Mon Sep 17 00:00:00 2001 From: Bryan Lima Date: Fri, 19 Apr 2024 14:37:02 -0300 Subject: [PATCH 10/13] Address reviews --- .../src/main/java/com/cloud/usage/UsageNetworksVO.java | 5 ++++- .../java/com/cloud/usage/parser/NetworksUsageParser.java | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java index 014857eef0c9..0cd095ceb097 100644 --- a/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java +++ b/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java @@ -62,7 +62,9 @@ public class UsageNetworksVO implements InternalIdentity { @Temporal(value = TemporalType.TIMESTAMP) private Date removed = null; - protected UsageNetworksVO(){} + protected UsageNetworksVO() { + + } public UsageNetworksVO(long id, long networkId, long networkOfferingId, long zoneId, long accountId, long domainId, String state, Date created, Date removed) { this.id = id; @@ -75,6 +77,7 @@ public UsageNetworksVO(long id, long networkId, long networkOfferingId, long zon this.created = created; this.removed = removed; } + public UsageNetworksVO(long networkId, long networkOfferingId, long zoneId, long accountId, long domainId, String state, Date created, Date removed) { this.networkId = networkId; this.networkOfferingId = networkOfferingId; diff --git a/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java index b11fb47154fc..9ebfaa31ce0b 100644 --- a/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java +++ b/usage/src/main/java/com/cloud/usage/parser/NetworksUsageParser.java @@ -25,6 +25,7 @@ import javax.inject.Inject; import org.apache.cloudstack.usage.UsageTypes; +import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -57,7 +58,7 @@ public static boolean parse(AccountVO account, Date startDate, Date endDate) { } final List usageNetworksVO = staticNetworksDao.getUsageRecords(account.getId(), startDate, endDate); - if (usageNetworksVO == null || usageNetworksVO.isEmpty()) { + if (CollectionUtils.isEmpty(usageNetworksVO)) { LOGGER.debug(String.format("Cannot find any VPC usage for account [%s] in period between [%s] and [%s].", account, startDate, endDate)); return true; } From d2e2c0cbffd849b77d3c7b1fe651891b480a18bf Mon Sep 17 00:00:00 2001 From: Bryan Lima Date: Mon, 22 Apr 2024 13:24:26 -0300 Subject: [PATCH 11/13] Address Daan review --- .../src/main/java/com/cloud/usage/UsageNetworksVO.java | 1 - usage/src/main/java/com/cloud/usage/UsageManagerImpl.java | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java b/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java index 0cd095ceb097..1385e69da038 100644 --- a/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java +++ b/engine/schema/src/main/java/com/cloud/usage/UsageNetworksVO.java @@ -63,7 +63,6 @@ public class UsageNetworksVO implements InternalIdentity { private Date removed = null; protected UsageNetworksVO() { - } public UsageNetworksVO(long id, long networkId, long networkOfferingId, long zoneId, long accountId, long domainId, String state, Date created, Date removed) { diff --git a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java index 040d25df5601..a52312095745 100644 --- a/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java +++ b/usage/src/main/java/com/cloud/usage/UsageManagerImpl.java @@ -2137,7 +2137,6 @@ private void createBackupEvent(final UsageEventVO event) { } } -<<<<<<< HEAD private void handleNetworkEvent(UsageEventVO event) { Account account = _accountDao.findByIdIncludingRemoved(event.getAccountId()); long domainId = account.getDomainId(); @@ -2150,7 +2149,9 @@ private void handleNetworkEvent(UsageEventVO event) { usageNetworksDao.update(event.getResourceId(), event.getOfferingId(), event.getResourceType()); } else { s_logger.error(String.format("Unknown event type [%s] in Networks event parser. Skipping it.", event.getType())); -======= + } + } + private void handleVpcEvent(UsageEventVO event) { Account account = _accountDao.findByIdIncludingRemoved(event.getAccountId()); long domainId = account.getDomainId(); @@ -2161,7 +2162,6 @@ private void handleVpcEvent(UsageEventVO event) { usageVpcDao.persist(usageVPCVO); } else { s_logger.error(String.format("Unknown event type [%s] in VPC event parser. Skipping it.", event.getType())); ->>>>>>> 21182dabcd8cdfbb20fc514c549837aa26a4ba45 } } From cbcf711a149eb7f3a650f9e6ba392eb563cbefe5 Mon Sep 17 00:00:00 2001 From: Bryan Lima <42067040+BryanMLima@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:11:58 -0300 Subject: [PATCH 12/13] Add missing constraints Co-authored-by: Henrique Sato --- .../src/main/resources/META-INF/db/schema-41900to41910.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql b/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql index c5b3f43b3e6f..c086ece469d5 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql @@ -41,8 +41,8 @@ CREATE TABLE IF NOT EXISTS `cloud_usage`.`usage_networks` ( `domain_id` bigint(20) unsigned NOT NULL, `state` varchar(100) DEFAULT NULL, `removed` datetime DEFAULT NULL, - `created` datetime NOT NULL, - + `created` datetime NOT NULL + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- allow for bigger urls ALTER TABLE `cloud`.`vm_template` MODIFY COLUMN `url` VARCHAR(1024) DEFAULT NULL COMMENT 'the url where the template exists externally'; From 9c2669ea00fdec67e9b2f18445f4b49cfea299be Mon Sep 17 00:00:00 2001 From: Bryan Lima Date: Tue, 23 Apr 2024 16:00:49 -0300 Subject: [PATCH 13/13] Add primary key on schema --- .../src/main/resources/META-INF/db/schema-41900to41910.sql | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql b/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql index c086ece469d5..c05f5503c3e2 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41900to41910.sql @@ -41,8 +41,10 @@ CREATE TABLE IF NOT EXISTS `cloud_usage`.`usage_networks` ( `domain_id` bigint(20) unsigned NOT NULL, `state` varchar(100) DEFAULT NULL, `removed` datetime DEFAULT NULL, - `created` datetime NOT NULL - ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + `created` datetime NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB CHARSET=utf8; + -- allow for bigger urls ALTER TABLE `cloud`.`vm_template` MODIFY COLUMN `url` VARCHAR(1024) DEFAULT NULL COMMENT 'the url where the template exists externally';