diff --git a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java index f8b0eb817ae..5c44d087b1c 100644 --- a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java +++ b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java @@ -2139,7 +2139,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } - HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), cpuUtil, rx, tx, numCpus, "host", totMem, freeMem, 0, 0); + HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(), cpuUtil, rx, tx, "host", totMem, freeMem, 0, 0); return new GetHostStatsAnswer(cmd, hostStats); } diff --git a/api/src/com/cloud/api/response/CapabilityResponse.java b/api/src/com/cloud/api/response/CapabilityResponse.java new file mode 100644 index 00000000000..079a5e6af51 --- /dev/null +++ b/api/src/com/cloud/api/response/CapabilityResponse.java @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.api.response; + +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class CapabilityResponse extends BaseResponse { + + @SerializedName(ApiConstants.NAME) @Param(description="the capability name") + private String name; + + @SerializedName(ApiConstants.VALUE) @Param(description="the capability value") + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/api/src/com/cloud/api/response/NetworkResponse.java b/api/src/com/cloud/api/response/NetworkResponse.java index b83852a3fb2..0c1df19f4e9 100644 --- a/api/src/com/cloud/api/response/NetworkResponse.java +++ b/api/src/com/cloud/api/response/NetworkResponse.java @@ -1,5 +1,7 @@ package com.cloud.api.response; +import java.util.List; + import com.cloud.api.ApiConstants; import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; @@ -102,6 +104,9 @@ public class NetworkResponse extends BaseResponse{ @SerializedName(ApiConstants.DOMAIN) @Param(description="the domain associated with the network") private String domain; + + @SerializedName("service") @Param(description="the list of services") + private List services; public Long getId() { return id; @@ -310,6 +315,12 @@ public class NetworkResponse extends BaseResponse{ public void setNetworkOfferingAvailability(String networkOfferingAvailability) { this.networkOfferingAvailability = networkOfferingAvailability; } - - + + public List getServices() { + return services; + } + + public void setServices(List services) { + this.services = services; + } } diff --git a/api/src/com/cloud/api/response/ServiceResponse.java b/api/src/com/cloud/api/response/ServiceResponse.java new file mode 100644 index 00000000000..d28c9f496ec --- /dev/null +++ b/api/src/com/cloud/api/response/ServiceResponse.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.api.response; + +import java.util.List; + +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class ServiceResponse extends BaseResponse { + + @SerializedName(ApiConstants.NAME) @Param(description="the service name") + private String name; + + @SerializedName("capability") @Param(description="the list of capabilities") + private List capabilities; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getCapabilities() { + return capabilities; + } + + public void setCapabilities(List capabilities) { + this.capabilities = capabilities; + } +} \ No newline at end of file diff --git a/api/src/com/cloud/api/response/UserVmResponse.java b/api/src/com/cloud/api/response/UserVmResponse.java index 3e34772a68b..40625421b9c 100644 --- a/api/src/com/cloud/api/response/UserVmResponse.java +++ b/api/src/com/cloud/api/response/UserVmResponse.java @@ -142,12 +142,12 @@ public class UserVmResponse extends BaseResponse { @SerializedName("jobstatus") @Param(description="shows the current pending asynchronous job status") private Integer jobStatus; + @SerializedName("nic") @Param(description="the list of nics associated with vm") + private List nics; + public Long getObjectId() { return getId(); } - - @SerializedName("nic") @Param(description="the list of nics associated with vm") - private List nics; public Long getId() { return id; diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 5d2053163f8..b7ea407758b 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -20,6 +20,73 @@ import com.cloud.utils.fsm.StateMachine; * owned by an account. */ public interface Network extends ControlledEntity { + + public static class Service { + + public static final Service Vpn = new Service("Vpn"); + public static final Service Dhcp = new Service("Dhcp"); + public static final Service Dns = new Service("Dns"); + public static final Service Gateway = new Service("Gateway"); + public static final Service Firewall = new Service("Firewall", Capability.PortForwarding, Capability.StaticNat); + public static final Service Lb = new Service("Lb"); + public static final Service UserData = new Service("UserData"); + + private String name; + private Capability[] caps; + + public Service(String name, Capability... caps) { + this.name = name; + } + + public String getName() { + return name; + } + + public Capability[] getCapabilities() { + return caps; + } + } + + public static class Provider { + + public static final Provider VirtualRouter = new Provider("VirtualRouter"); + public static final Provider DhcpServer = new Provider("DhcpServer"); + public static final Provider ExternalFirewall = new Provider("ExternalFirewall"); + public static final Provider ExternalLoadBalancer = new Provider("ExternalLoadBalancer"); + + private String name; + + public Provider(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + public static class Capability { + + public static final Capability PortForwarding = new Capability("PortForwarding"); + public static final Capability StaticNat = new Capability("StaticNat"); + public static final Capability SupportedProtocols = new Capability("SupportedProtocols"); + public static final Capability SupportedLBAlgorithms = new Capability("SupportedLBAlgorithms"); + public static final Capability Vpn = new Capability("VPN"); + public static final Capability MultipleIps = new Capability("MultipleIps"); + public static final Capability SupportedSourceNatTypes = new Capability("SupportedSourceNatTypes"); + public static final Capability SupportedVpnTypes = new Capability("SupportedVpnTypes"); + + private String name; + + public Capability(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + enum Event { ImplementNetwork, DestroyNetwork, @@ -114,4 +181,5 @@ public interface Network extends ControlledEntity { boolean isShared(); String getReservationId(); + } diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 2471ff5f3e9..d71f6e712ca 100644 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -90,4 +90,5 @@ public interface NetworkService { boolean restartNetwork(RestartNetworkCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException; int getActiveNicsInNetwork(long networkId); + } diff --git a/api/src/com/cloud/network/element/NetworkElement.java b/api/src/com/cloud/network/element/NetworkElement.java index 4854a391ec0..9586e7ae59e 100644 --- a/api/src/com/cloud/network/element/NetworkElement.java +++ b/api/src/com/cloud/network/element/NetworkElement.java @@ -4,6 +4,7 @@ package com.cloud.network.element; import java.util.List; +import java.util.Map; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; @@ -11,6 +12,9 @@ import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientNetworkCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; import com.cloud.network.PublicIpAddress; import com.cloud.network.rules.FirewallRule; import com.cloud.offering.NetworkOffering; @@ -24,6 +28,11 @@ import com.cloud.vm.VirtualMachineProfile; * Represents one network element that exists in a network. */ public interface NetworkElement extends Adapter { + + Map> getCapabilities(); + + Provider getProvider(); + /** * Implement the network configuration as specified. * @param config fully specified network configuration. diff --git a/build/deploy/production/premium/conf/usage-components.xml b/build/deploy/production/premium/conf/usage-components.xml index 5e178302819..37d66abe715 100644 --- a/build/deploy/production/premium/conf/usage-components.xml +++ b/build/deploy/production/premium/conf/usage-components.xml @@ -29,7 +29,6 @@ 50 -1 - @@ -41,6 +40,8 @@ + + DAILY diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index 371c8239472..7dfdbbb2e67 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -96,6 +96,6 @@ - + diff --git a/core/src/com/cloud/agent/api/GetHostStatsAnswer.java b/core/src/com/cloud/agent/api/GetHostStatsAnswer.java index c209ac84047..8d5a8ce152c 100755 --- a/core/src/com/cloud/agent/api/GetHostStatsAnswer.java +++ b/core/src/com/cloud/agent/api/GetHostStatsAnswer.java @@ -17,8 +17,6 @@ */ package com.cloud.agent.api; -import java.util.HashMap; - import com.cloud.host.HostStats; /** @@ -28,18 +26,9 @@ import com.cloud.host.HostStats; public class GetHostStatsAnswer extends Answer implements HostStats { HostStatsEntry hostStats; - - double cpuUtilization; - double networkReadKBs; - double networkWriteKBs; - int numCPUs; - String entityType; - double totalMemoryKBs; - double freeMemoryKBs; - double xapiMemoryUsageKBs; - double averageLoad; - + protected GetHostStatsAnswer() { + hostStats = new HostStatsEntry(); } public GetHostStatsAnswer(GetHostStatsCommand cmd, HostStatsEntry hostStatistics) { @@ -48,67 +37,51 @@ public class GetHostStatsAnswer extends Answer implements HostStats { } public GetHostStatsAnswer(GetHostStatsCommand cmd, double cpuUtilization, double freeMemoryKBs, double totalMemoryKBs, double networkReadKBs, - double networkWriteKBs, String entityType, double xapiMemoryUsageKBs, double averageLoad, int numCPUs) { + double networkWriteKBs, String entityType) { super(cmd); - - this.cpuUtilization = cpuUtilization; - this.freeMemoryKBs = freeMemoryKBs; - this.totalMemoryKBs = totalMemoryKBs; - this.networkReadKBs = networkReadKBs; - this.networkWriteKBs = networkWriteKBs; - this.entityType = entityType; - this.xapiMemoryUsageKBs = xapiMemoryUsageKBs; - this.numCPUs = numCPUs; + hostStats = new HostStatsEntry(); + + hostStats.setCpuUtilization(cpuUtilization); + hostStats.setFreeMemoryKBs(freeMemoryKBs); + hostStats.setTotalMemoryKBs(totalMemoryKBs); + hostStats.setNetworkReadKBs(networkReadKBs); + hostStats.setNetworkWriteKBs(networkWriteKBs); + hostStats.setEntityType(entityType); } @Override public double getUsedMemory() { - return (totalMemoryKBs - freeMemoryKBs); + return hostStats.getUsedMemory(); } @Override public double getFreeMemoryKBs() { - return freeMemoryKBs; + return hostStats.getFreeMemoryKBs(); } @Override public double getTotalMemoryKBs() { - return totalMemoryKBs; + return hostStats.getTotalMemoryKBs(); } @Override public double getCpuUtilization() { - return cpuUtilization; + return hostStats.getCpuUtilization(); } @Override public double getNetworkReadKBs() { - return networkReadKBs; + return hostStats.getNetworkReadKBs(); } @Override public double getNetworkWriteKBs() { - return networkWriteKBs; + return hostStats.getNetworkWriteKBs(); } - @Override - public double getAverageLoad() { - return averageLoad; - } - @Override public String getEntityType() { - return entityType; - } - - @Override - public double getXapiMemoryUsageKBs() { - return xapiMemoryUsageKBs; - } - - @Override - public int getNumCpus(){ - return numCPUs; + return hostStats.getEntityType(); } @Override diff --git a/core/src/com/cloud/agent/api/HostStatsEntry.java b/core/src/com/cloud/agent/api/HostStatsEntry.java index 65248aaa120..4b0c80b0fdb 100644 --- a/core/src/com/cloud/agent/api/HostStatsEntry.java +++ b/core/src/com/cloud/agent/api/HostStatsEntry.java @@ -26,43 +26,28 @@ import com.cloud.host.HostStats; public class HostStatsEntry implements HostStats { long hostId; + String entityType; double cpuUtilization; double networkReadKBs; double networkWriteKBs; - int numCpus; - String entityType; double totalMemoryKBs; double freeMemoryKBs; - double xapiMemoryUsageKBs; - double averageLoad; public HostStatsEntry() { } - public HostStatsEntry(long hostId,double cpuUtilization, double networkReadKBs, double networkWriteKBs, int numCPUs, String entityType, - double totalMemoryKBs, double freeMemoryKBs, double xapiMemoryUsageKBs, double averageLoad) + public HostStatsEntry(long hostId,double cpuUtilization, double networkReadKBs, double networkWriteKBs, String entityType, + double totalMemoryKBs, double freeMemoryKBs, double xapiMemoryUsageKBs, double averageLoad) { + this.hostId = hostId; + this.entityType = entityType; this.cpuUtilization = cpuUtilization; this.networkReadKBs = networkReadKBs; this.networkWriteKBs = networkWriteKBs; - this.numCpus = numCPUs; - this.entityType = entityType; this.totalMemoryKBs = totalMemoryKBs; this.freeMemoryKBs = freeMemoryKBs; - this.xapiMemoryUsageKBs = xapiMemoryUsageKBs; - this.averageLoad = averageLoad; - this.hostId = hostId; } - @Override - public double getAverageLoad() { - return averageLoad; - } - - public void setAverageLoad(double averageLoad) { - this.averageLoad = averageLoad; - } - @Override public double getNetworkReadKBs() { return networkReadKBs; @@ -80,10 +65,6 @@ public class HostStatsEntry implements HostStats { public void setNetworkWriteKBs(double networkWriteKBs) { this.networkWriteKBs = networkWriteKBs; } - - public void setNumCpus(int numCpus) { - this.numCpus = numCpus; - } @Override public String getEntityType(){ @@ -112,15 +93,6 @@ public class HostStatsEntry implements HostStats { this.freeMemoryKBs = freeMemoryKBs; } - @Override - public double getXapiMemoryUsageKBs(){ - return this.xapiMemoryUsageKBs; - } - - public void setXapiMemoryUsageKBs(double xapiMemoryUsageKBs){ - this.xapiMemoryUsageKBs = xapiMemoryUsageKBs; - } - @Override public double getCpuUtilization() { return this.cpuUtilization; @@ -135,14 +107,12 @@ public class HostStatsEntry implements HostStats { return (totalMemoryKBs-freeMemoryKBs); } - @Override - public int getNumCpus() { - return numCpus; - } - @Override public HostStats getHostStats() { - // TODO Auto-generated method stub - return null; + return this; + } + + public void setHostId(long hostId) { + this.hostId = hostId; } } diff --git a/core/src/com/cloud/agent/api/SetupAnswer.java b/core/src/com/cloud/agent/api/SetupAnswer.java index 6475560bcf6..1257e4975e8 100644 --- a/core/src/com/cloud/agent/api/SetupAnswer.java +++ b/core/src/com/cloud/agent/api/SetupAnswer.java @@ -18,17 +18,21 @@ package com.cloud.agent.api; public class SetupAnswer extends Answer { + // indicate if agent reconnect is needed after setup command + private boolean _reconnect; public SetupAnswer() {} - public SetupAnswer(SetupCommand cmd) { + public SetupAnswer(SetupCommand cmd, boolean reconnect) { super(cmd, true, null); + _reconnect = reconnect; } - - public SetupAnswer(SetupCommand cmd, boolean result, String details) { - super(cmd, result, details); - } - + public SetupAnswer(SetupCommand cmd, String details) { super(cmd, false, details); + _reconnect = true; } + public boolean needReconnect() { + return _reconnect; + } + } diff --git a/api/src/com/cloud/network/service/Providers.java b/core/src/com/cloud/event/UsageEvent.java similarity index 72% rename from api/src/com/cloud/network/service/Providers.java rename to core/src/com/cloud/event/UsageEvent.java index 5556fd94394..c90840afce2 100644 --- a/api/src/com/cloud/network/service/Providers.java +++ b/core/src/com/cloud/event/UsageEvent.java @@ -15,10 +15,19 @@ * along with this program. If not, see . * */ -package com.cloud.network.service; +package com.cloud.event; -public class Providers { - public final static String VirtualRouter = "VirtualRouter"; - public final static String ExternalFirewall = "ExternalFirewall"; - public final static String ExternalLoadBalancer = "ExternalLoadBalancer"; +import java.util.Date; + +public interface UsageEvent { + long getId(); + String getType(); + + Date getCreateDate(); + long getAccountId(); + Long getSize(); + Long getTemplateId(); + Long getOfferingId(); + long getResourceId(); + long getZoneId(); } diff --git a/core/src/com/cloud/event/UsageEventVO.java b/core/src/com/cloud/event/UsageEventVO.java new file mode 100644 index 00000000000..4390978b8bf --- /dev/null +++ b/core/src/com/cloud/event/UsageEventVO.java @@ -0,0 +1,169 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.event; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.SecondaryTable; +import javax.persistence.Table; + +import com.cloud.utils.db.GenericDao; + +@Entity +@Table(name="usage_event") +@SecondaryTable(name="account", + pkJoinColumns={@PrimaryKeyJoinColumn(name="account_id", referencedColumnName="id")}) +public class UsageEventVO implements UsageEvent { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + private long id = -1; + + @Column(name="type") + private String type; + + @Column(name=GenericDao.CREATED_COLUMN) + private Date createDate; + + @Column(name="account_id") + private long accountId; + + @Column(name="zone_id") + private long zoneId; + + @Column(name="resource_id") + private long resourceId; + + @Column(name="resource_name") + private String resourceName; + + @Column(name="offering_id") + private Long offeringId; + + @Column(name="template_id") + private Long templateId; + + @Column(name="size") + private Long size; + + + public UsageEventVO() { + } + + public UsageEventVO(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, Long size) { + this.type = usageType; + this.accountId = accountId; + this.zoneId = zoneId; + this.resourceId = resourceId; + this.resourceName = resourceName; + this.offeringId = offeringId; + this.templateId = templateId; + this.size = size; + } + + public UsageEventVO(String usageType, long accountId, long zoneId, long resourceId, String resourceName) { + this.type = usageType; + this.accountId = accountId; + this.zoneId = zoneId; + this.resourceId = resourceId; + this.resourceName = resourceName; + } + + public long getId() { + return id; + } + @Override + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + + @Override + public Date getCreateDate() { + return createDate; + } + public void setCreatedDate(Date createdDate) { + createDate = createdDate; + } + + @Override + public long getAccountId() { + return accountId; + } + public void setAccountId(long accountId) { + this.accountId = accountId; + } + + public void setZoneId(long zoneId) { + this.zoneId = zoneId; + } + @Override + public long getZoneId() { + return zoneId; + } + + public void setResourceId(long resourceId) { + this.resourceId = resourceId; + } + @Override + public long getResourceId() { + return resourceId; + } + + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + public String getResourceName() { + return resourceName; + } + + public void setOfferingId(long offeringId) { + this.offeringId = offeringId; + } + @Override + public Long getOfferingId() { + return offeringId; + } + + public void setTemplateId(long templateId) { + this.templateId = templateId; + } + @Override + public Long getTemplateId() { + return templateId; + } + + public void setSize(long size) { + this.size = size; + } + @Override + public Long getSize() { + return size; + } + +} diff --git a/core/src/com/cloud/event/dao/UsageEventDao.java b/core/src/com/cloud/event/dao/UsageEventDao.java new file mode 100644 index 00000000000..271856b2f5d --- /dev/null +++ b/core/src/com/cloud/event/dao/UsageEventDao.java @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.event.dao; + +import java.util.Date; +import java.util.List; + +import com.cloud.event.UsageEventVO; +import com.cloud.exception.UsageServerException; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.GenericDao; +import com.cloud.utils.db.SearchCriteria; + +public interface UsageEventDao extends GenericDao { + + public List searchAllUsageEvents(SearchCriteria sc, Filter filter); + + public List listLatestEvents(Date recentEventDate, Date endDate); + + public List listAllEvents(Date endDate); + + public List getLatestEventDate(); + + List getRecentEvents(Date endDate) throws UsageServerException; + +} \ No newline at end of file diff --git a/core/src/com/cloud/event/dao/UsageEventDaoImpl.java b/core/src/com/cloud/event/dao/UsageEventDaoImpl.java new file mode 100644 index 00000000000..170892dd95e --- /dev/null +++ b/core/src/com/cloud/event/dao/UsageEventDaoImpl.java @@ -0,0 +1,163 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.event.dao; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.event.UsageEventVO; +import com.cloud.exception.UsageServerException; +import com.cloud.utils.DateUtil; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; + +@Local(value={UsageEventDao.class}) +public class UsageEventDaoImpl extends GenericDaoBase implements UsageEventDao { + public static final Logger s_logger = Logger.getLogger(UsageEventDaoImpl.class.getName()); + + private final SearchBuilder latestEventsSearch; + private final SearchBuilder allEventsSearch; + private static final String GET_LATEST_EVENT_DATE = "SELECT created FROM usage_event ORDER BY created DESC LIMIT 1"; + private static final String COPY_EVENTS = "INSERT INTO cloud_usage.usage_event SELECT id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size FROM cloud.usage_event vmevt WHERE vmevt.created > ? and vmevt.created <= ? "; + private static final String COPY_ALL_EVENTS = "INSERT INTO cloud_usage.usage_event SELECT id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size FROM cloud.usage_event where created <= ? "; + + + public UsageEventDaoImpl () { + latestEventsSearch = createSearchBuilder(); + latestEventsSearch.and("recentEventDate", latestEventsSearch.entity().getCreateDate(), SearchCriteria.Op.GT); + latestEventsSearch.and("enddate", latestEventsSearch.entity().getCreateDate(), SearchCriteria.Op.LTEQ); + latestEventsSearch.done(); + + allEventsSearch = createSearchBuilder(); + allEventsSearch.and("enddate", allEventsSearch.entity().getCreateDate(), SearchCriteria.Op.LTEQ); + allEventsSearch.done(); + + } + + @Override + public List listLatestEvents(Date recentEventDate, Date endDate) { + Filter filter = new Filter(UsageEventVO.class, "createDate", Boolean.TRUE, null, null); + SearchCriteria sc = latestEventsSearch.create(); + sc.setParameters("recentEventDate", recentEventDate); + sc.setParameters("enddate", endDate); + return listBy(sc, filter); + } + + @Override + public List listAllEvents(Date endDate) { + Filter filter = new Filter(UsageEventVO.class, "createDate", Boolean.TRUE, null, null); + SearchCriteria sc = latestEventsSearch.create(); + sc.setParameters("enddate", endDate); + return listBy(sc, filter); + } + + @Override + public List getLatestEventDate() { + Filter filter = new Filter(UsageEventVO.class, "createDate", Boolean.FALSE, null, 1L); + return listAll(filter); + } + + @Override + public List searchAllUsageEvents(SearchCriteria sc, Filter filter) { + return listIncludingRemovedBy(sc, filter); + } + + + public synchronized List getRecentEvents(Date endDate) throws UsageServerException { + Transaction txn = Transaction.open(Transaction.USAGE_DB); + Date recentEventDate = getMostRecentEventDate(); + String sql = COPY_EVENTS; + if (recentEventDate == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("no recent event date, copying all events"); + } + sql = COPY_ALL_EVENTS; + } + + PreparedStatement pstmt = null; + try { + txn.start(); + pstmt = txn.prepareAutoCloseStatement(sql); + int i = 1; + if (recentEventDate != null) { + pstmt.setString(i++, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), recentEventDate)); + } + pstmt.setString(i, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), endDate)); + pstmt.executeUpdate(); + txn.commit(); + return findRecentEvents(recentEventDate, endDate); + } catch (Exception ex) { + txn.rollback(); + s_logger.error("error copying events from cloud db to usage db", ex); + throw new UsageServerException(ex.getMessage()); + } finally { + txn.close(); + } + } + + private Date getMostRecentEventDate() throws UsageServerException { + Transaction txn = Transaction.open(Transaction.USAGE_DB); + PreparedStatement pstmt = null; + String sql = GET_LATEST_EVENT_DATE; + try { + pstmt = txn.prepareAutoCloseStatement(sql); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) { + String mostRecentTimestampStr = rs.getString(1); + if (mostRecentTimestampStr != null) { + return DateUtil.parseDateString(s_gmtTimeZone, mostRecentTimestampStr); + } + } + } catch (Exception ex) { + s_logger.error("error getting most recent event date", ex); + throw new UsageServerException(ex.getMessage()); + } finally { + txn.close(); + } + return null; + } + + private List findRecentEvents(Date recentEventDate, Date endDate) throws UsageServerException { + Transaction txn = Transaction.open(Transaction.USAGE_DB); + try { + int i = 1; + if (recentEventDate == null) { + return listAllEvents(endDate); + } else { + return listLatestEvents(recentEventDate, endDate); + } + } catch (Exception ex) { + s_logger.error("error getting most recent event date", ex); + throw new UsageServerException(ex.getMessage()); + } finally { + txn.close(); + } + } + +} diff --git a/core/src/com/cloud/host/HostStats.java b/core/src/com/cloud/host/HostStats.java index 128754bf6ca..d35a5c6d851 100755 --- a/core/src/com/cloud/host/HostStats.java +++ b/core/src/com/cloud/host/HostStats.java @@ -23,16 +23,16 @@ package com.cloud.host; */ public interface HostStats { - //host related stats - public double getAverageLoad(); + // host related stats public double getCpuUtilization(); public double getNetworkWriteKBs(); public double getTotalMemoryKBs(); public double getFreeMemoryKBs(); - public double getXapiMemoryUsageKBs(); public double getNetworkReadKBs(); public String getEntityType(); public double getUsedMemory(); - public int getNumCpus(); public HostStats getHostStats(); + + // public double getAverageLoad(); + // public double getXapiMemoryUsageKBs(); } diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index e9555a19e67..8c4f6669120 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -932,7 +932,7 @@ public abstract class CitrixResourceBase implements ServerResource { } protected SetupAnswer execute(SetupCommand cmd) { - return new SetupAnswer(cmd); + return new SetupAnswer(cmd, false); } protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesCommand cmd) { @@ -1395,7 +1395,7 @@ public abstract class CitrixResourceBase implements ServerResource { protected HostStatsEntry getHostStats(Connection conn, GetHostStatsCommand cmd, String hostGuid, long hostId) { - HostStatsEntry hostStats = new HostStatsEntry(hostId, 0, 0, 0, 0, "host", 0, 0, 0, 0); + HostStatsEntry hostStats = new HostStatsEntry(hostId, 0, 0, 0, "host", 0, 0, 0, 0); Object[] rrdData = getRRDData(conn, 1); // call rrd method with 1 for host if (rrdData == null) { @@ -1448,21 +1448,25 @@ public abstract class CitrixResourceBase implements ServerResource { } if (param.contains("cpu")) { - hostStats.setNumCpus(hostStats.getNumCpus() + 1); + // hostStats.setNumCpus(hostStats.getNumCpus() + 1); hostStats.setCpuUtilization(hostStats.getCpuUtilization() + getDataAverage(dataNode, col, numRows)); } +/* if (param.contains("loadavg")) { hostStats.setAverageLoad((hostStats.getAverageLoad() + getDataAverage(dataNode, col, numRows))); } +*/ } } // add the host cpu utilization +/* if (hostStats.getNumCpus() != 0) { hostStats.setCpuUtilization(hostStats.getCpuUtilization() / hostStats.getNumCpus()); s_logger.debug("Host cpu utilization " + hostStats.getCpuUtilization()); } +*/ return hostStats; } diff --git a/patches/systemvm/debian/config/bin/vhd-util b/patches/systemvm/debian/config/bin/vhd-util new file mode 100755 index 00000000000..12a13927821 Binary files /dev/null and b/patches/systemvm/debian/config/bin/vhd-util differ diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 1aed0885da8..7f1b25b7b46 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -2,6 +2,7 @@ package com.cloud.api; import java.util.ArrayList; import java.util.List; +import java.util.Map; import com.cloud.agent.AgentManager; import com.cloud.async.AsyncJobManager; @@ -32,6 +33,8 @@ import com.cloud.network.Network; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkRuleConfigVO; import com.cloud.network.NetworkVO; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Service; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; @@ -508,4 +511,8 @@ public class ApiDBUtils { return _networkDao.findById(id); } + public static Map> getZoneCapabilities(long zoneId) { + return _networkMgr.getZoneCapabilities(zoneId); + } + } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 0cb29aa5434..80654cf1628 100644 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -34,6 +34,7 @@ import com.cloud.api.commands.QueryAsyncJobResultCmd; import com.cloud.api.response.AccountResponse; import com.cloud.api.response.ApiResponseSerializer; import com.cloud.api.response.AsyncJobResponse; +import com.cloud.api.response.CapabilityResponse; import com.cloud.api.response.CapacityResponse; import com.cloud.api.response.ClusterResponse; import com.cloud.api.response.ConfigurationResponse; @@ -60,6 +61,7 @@ import com.cloud.api.response.RemoteAccessVpnResponse; import com.cloud.api.response.ResourceLimitResponse; import com.cloud.api.response.SecurityGroupResponse; import com.cloud.api.response.ServiceOfferingResponse; +import com.cloud.api.response.ServiceResponse; import com.cloud.api.response.SnapshotPolicyResponse; import com.cloud.api.response.SnapshotResponse; import com.cloud.api.response.StoragePoolResponse; @@ -97,6 +99,8 @@ import com.cloud.host.HostStats; import com.cloud.host.HostVO; import com.cloud.network.IpAddress; import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Service; import com.cloud.network.Networks.TrafficType; import com.cloud.network.RemoteAccessVpn; import com.cloud.network.VpnUser; @@ -498,7 +502,7 @@ public class ApiResponseHelper implements ResponseGenerator { float cpuUtil = (float) hostStats.getCpuUtilization(); cpuUsed = decimalFormat.format(cpuUtil) + "%"; hostResponse.setCpuUsed(cpuUsed); - hostResponse.setAverageLoad(Double.doubleToLongBits(hostStats.getAverageLoad())); + // hostResponse.setAverageLoad(Double.doubleToLongBits(hostStats.getAverageLoad())); hostResponse.setNetworkKbsRead(Double.doubleToLongBits(hostStats.getNetworkReadKBs())); hostResponse.setNetworkKbsWrite(Double.doubleToLongBits(hostStats.getNetworkWriteKBs())); } @@ -2209,7 +2213,36 @@ public class ApiResponseHelper implements ResponseGenerator { response.setRelated(network.getRelated()); response.setDns1(network.getDns1()); response.setDns2(network.getDns2()); - + + //populate capability + Map> serviceCapabilitiesMap = ApiDBUtils.getZoneCapabilities(network.getDataCenterId()); + List serviceResponses = new ArrayList(); + if (serviceCapabilitiesMap != null) { + for (Service service : serviceCapabilitiesMap.keySet()) { + ServiceResponse serviceResponse = new ServiceResponse(); + serviceResponse.setName(service.getName()); + + //set list of capabilities for the service + List capabilityResponses = new ArrayList(); + Map serviceCapabilities = serviceCapabilitiesMap.get(service); + if (serviceCapabilities != null) { + for (Capability capability : serviceCapabilities.keySet()) { + CapabilityResponse capabilityResponse = new CapabilityResponse(); + String capabilityValue = serviceCapabilities.get(capability); + capabilityResponse.setName(capability.getName()); + capabilityResponse.setValue(capabilityValue); + capabilityResponse.setObjectName("capability"); + capabilityResponses.add(capabilityResponse); + } + serviceResponse.setCapabilities(capabilityResponses); + } + + serviceResponse.setObjectName("service"); + serviceResponses.add(serviceResponse); + } + } + response.setServices(serviceResponses); + Account account = ApiDBUtils.findAccountById(network.getAccountId()); if (account != null) { response.setAccountName(account.getAccountName()); diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index ec72d6cab7c..e43391a1248 100644 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -52,6 +52,7 @@ import com.cloud.dc.dao.PodVlanMapDaoImpl; import com.cloud.dc.dao.VlanDaoImpl; import com.cloud.domain.dao.DomainDaoImpl; import com.cloud.event.dao.EventDaoImpl; +import com.cloud.event.dao.UsageEventDaoImpl; import com.cloud.ha.HighAvailabilityManagerImpl; import com.cloud.ha.dao.HighAvailabilityDaoImpl; import com.cloud.host.dao.DetailsDaoImpl; @@ -113,12 +114,12 @@ import com.cloud.user.dao.UserStatisticsDaoImpl; import com.cloud.utils.Pair; import com.cloud.utils.component.Adapter; import com.cloud.utils.component.ComponentLibrary; -import com.cloud.utils.component.ComponentLocator.ComponentInfo; import com.cloud.utils.component.Manager; +import com.cloud.utils.component.ComponentLocator.ComponentInfo; import com.cloud.utils.db.GenericDao; import com.cloud.vm.ItWorkDaoImpl; -import com.cloud.vm.VirtualMachineManagerImpl; import com.cloud.vm.UserVmManagerImpl; +import com.cloud.vm.VirtualMachineManagerImpl; import com.cloud.vm.dao.ConsoleProxyDaoImpl; import com.cloud.vm.dao.DomainRouterDaoImpl; import com.cloud.vm.dao.InstanceGroupDaoImpl; @@ -231,6 +232,7 @@ public class DefaultComponentLibrary implements ComponentLibrary { addDao("ItWorkDao", ItWorkDaoImpl.class); addDao("FirewallRulesDao", FirewallRulesDaoImpl.class); addDao("PortForwardingRulesDao", PortForwardingRulesDaoImpl.class); + addDao("UsageEventDao", UsageEventDaoImpl.class); } Map> _managers = new HashMap>(); diff --git a/server/src/com/cloud/dc/DataCenterVO.java b/server/src/com/cloud/dc/DataCenterVO.java index e31cd079301..8ef823c5c23 100644 --- a/server/src/com/cloud/dc/DataCenterVO.java +++ b/server/src/com/cloud/dc/DataCenterVO.java @@ -28,7 +28,7 @@ import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.TableGenerator; -import com.cloud.network.service.Providers; +import com.cloud.network.Network.Provider; @Entity @Table(name="data_center") @@ -77,13 +77,13 @@ public class DataCenterVO implements DataCenter { NetworkType networkType; @Column(name="dns_provider") - private String dnsProvider = "VirtualRouter"; + private String dnsProvider = Provider.VirtualRouter.getName(); @Column(name="dhcp_provider") - private String dhcpProvider = "VirtualRouter"; + private String dhcpProvider = Provider.VirtualRouter.getName(); @Column(name="gateway_provider") - private String gatewayProvider = "VirtualRouter"; + private String gatewayProvider = Provider.VirtualRouter.getName(); @Column(name="vpn_provider") private String vpnProvider; @@ -163,13 +163,13 @@ public class DataCenterVO implements DataCenter { this.domain = domain; this.domainId = domainId; this.networkType = zoneType; - loadBalancerProvider = Providers.VirtualRouter; - firewallProvider = Providers.VirtualRouter; - dhcpProvider = Providers.VirtualRouter; - dnsProvider = Providers.VirtualRouter; - gatewayProvider = Providers.VirtualRouter; - vpnProvider = Providers.VirtualRouter; - userDataProvider = Providers.VirtualRouter; + loadBalancerProvider = Provider.VirtualRouter.getName(); + firewallProvider = Provider.VirtualRouter.getName(); + dhcpProvider = Provider.VirtualRouter.getName(); + dnsProvider = Provider.VirtualRouter.getName(); + gatewayProvider = Provider.VirtualRouter.getName(); + vpnProvider = Provider.VirtualRouter.getName(); + userDataProvider = Provider.VirtualRouter.getName(); } @Override diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 6a302bdb42d..884288bdca9 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -18,6 +18,7 @@ package com.cloud.network; import java.util.List; +import java.util.Map; import com.cloud.dc.Vlan.VlanType; import com.cloud.deploy.DeployDestination; @@ -26,6 +27,8 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Service; import com.cloud.network.addr.PublicIp; import com.cloud.network.rules.FirewallRule; import com.cloud.offerings.NetworkOfferingVO; @@ -123,4 +126,6 @@ public interface NetworkManager extends NetworkService { String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException; boolean applyRules(List rules, boolean continueOnError) throws ResourceUnavailableException; + + Map> getZoneCapabilities(long zoneId); } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 96eab58ca5b..1e9f9b637a9 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -24,6 +24,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.Executors; @@ -74,7 +75,9 @@ import com.cloud.domain.dao.DomainDao; import com.cloud.event.EventTypes; import com.cloud.event.EventUtils; import com.cloud.event.EventVO; +import com.cloud.event.UsageEventVO; import com.cloud.event.dao.EventDao; +import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.AccountLimitException; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; @@ -85,6 +88,8 @@ import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Service; import com.cloud.network.Networks.AddressFormat; import com.cloud.network.Networks.Availability; import com.cloud.network.Networks.BroadcastDomainType; @@ -188,6 +193,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Inject FirewallRulesDao _firewallRulesDao; @Inject LoadBalancerDao _lbDao; @Inject PortForwardingRulesDao _pfRulesDao; + @Inject UsageEventDao _usageEventDao; @Inject(adapter=NetworkGuru.class) Adapters _networkGurus; @@ -251,6 +257,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (!_ipAddressDao.update(addr.getAddress(), addr)) { throw new CloudRuntimeException("Found address to allocate but unable to update: " + addr); } + if(!sourceNat){ + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_ASSIGN, owner.getAccountId(), dcId, 0, addr.getAddress()); + _usageEventDao.persist(usageEvent); + } txn.commit(); long macAddress = NetUtils.createSequenceBasedMacAddress(addr.getMacAddress()); @@ -664,7 +674,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (success) { _ipAddressDao.unassignIpAddress(ipAddress); - s_logger.debug("released a public ip: " + ipAddress); + s_logger.debug("released a public ip: " + ipAddress); + if(!ip.isSourceNat()){ + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_RELEASE, ownerId, ip.getDataCenterId(), 0, ipAddress); + _usageEventDao.persist(usageEvent); + } } final EventVO event = new EventVO(); @@ -1770,7 +1784,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw new CloudRuntimeException("Failed to create a vlan"); } } - txn.commit(); + txn.commit(); + return networks.get(0); } catch (Exception ex) { s_logger.warn("Unexpected exception while creating network ", ex); @@ -1867,7 +1882,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } sc.addAnd("accountId", SearchCriteria.Op.SC, ssc); - return _networksDao.search(sc, searchFilter); + List networks = _networksDao.search(sc, searchFilter); + + return networks; } @Override @DB @@ -2120,4 +2137,43 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag public int getActiveNicsInNetwork(long networkId) { return _networksDao.getActiveNicsIn(networkId); } + + @Override + public Map> getZoneCapabilities(long zoneId) { + DataCenterVO dc = _dcDao.findById(zoneId); + if (dc == null) { + throw new InvalidParameterValueException("Zone id=" + dc.getId() + " doesn't exist in the system."); + } + + //Get all service providers from the datacenter + Map providers = new HashMap(); + providers.put(Service.Firewall, dc.getFirewallProvider()); + providers.put(Service.Lb, dc.getLoadBalancerProvider()); + providers.put(Service.Vpn, dc.getVpnProvider()); + providers.put(Service.Dns, dc.getDnsProvider()); + providers.put(Service.Gateway, dc.getGatewayProvider()); + providers.put(Service.UserData, dc.getUserDataProvider()); + providers.put(Service.Dhcp, dc.getDhcpProvider()); + + Map> networkCapabilities = new HashMap>(); + + for (NetworkElement element : _networkElements) { + if (providers.isEmpty()) { + break; + } + Map> elementCapabilities = element.getCapabilities(); + if (elementCapabilities != null) { + Iterator it = providers.keySet().iterator(); + while (it.hasNext()) { + Service service = it.next(); + if (providers.get(service).equals(element.getProvider().getName())) { + networkCapabilities.put(service, elementCapabilities.get(service)); + it.remove(); + } + } + } + } + return networkCapabilities; + } + } diff --git a/server/src/com/cloud/network/NetworkVO.java b/server/src/com/cloud/network/NetworkVO.java index 8dcbd0d39cd..e62655ceca8 100644 --- a/server/src/com/cloud/network/NetworkVO.java +++ b/server/src/com/cloud/network/NetworkVO.java @@ -130,7 +130,7 @@ public class NetworkVO implements Network { Date created; @Column(name="reservation_id") - String reservationId; + String reservationId; public NetworkVO() { } diff --git a/server/src/com/cloud/network/element/DhcpElement.java b/server/src/com/cloud/network/element/DhcpElement.java index 6b8bc98fc88..30f5805a663 100644 --- a/server/src/com/cloud/network/element/DhcpElement.java +++ b/server/src/com/cloud/network/element/DhcpElement.java @@ -17,7 +17,9 @@ */ package com.cloud.network.element; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.ejb.Local; @@ -29,12 +31,14 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; import com.cloud.network.NetworkManager; import com.cloud.network.PublicIpAddress; import com.cloud.network.dao.NetworkDao; import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.rules.FirewallRule; -import com.cloud.network.service.Providers; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.uservm.UserVm; @@ -51,9 +55,11 @@ import com.cloud.vm.dao.UserVmDao; @Local(value=NetworkElement.class) -public class DhcpElement extends AdapterBase implements NetworkElement { +public class DhcpElement extends AdapterBase implements NetworkElement{ private static final Logger s_logger = Logger.getLogger(DhcpElement.class); + private static final Map> capabilities = setCapabilities(); + @Inject NetworkDao _networkConfigDao; @Inject NetworkManager _networkMgr; @Inject VirtualNetworkApplianceManager _routerMgr; @@ -64,10 +70,10 @@ public class DhcpElement extends AdapterBase implements NetworkElement { private boolean canHandle(GuestIpType ipType, DeployDestination dest) { DataCenter dc = dest.getDataCenter(); String provider = dc.getGatewayProvider(); - if (!dc.getDhcpProvider().equals(Providers.VirtualRouter)) { + if (!dc.getDhcpProvider().equals(Provider.VirtualRouter.getName())) { return false; } - return ((ipType == GuestIpType.Virtual && !provider.equals(Providers.VirtualRouter)) || (ipType == GuestIpType.Direct || ipType == GuestIpType.DirectPodBased)); + return ((ipType == GuestIpType.Virtual && !provider.equals(Provider.VirtualRouter.getName())) || (ipType == GuestIpType.Direct || ipType == GuestIpType.DirectPodBased)); } @Override @@ -100,7 +106,7 @@ public class DhcpElement extends AdapterBase implements NetworkElement { public boolean release(Network config, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) { return true; } - + @Override public boolean shutdown(Network config, ReservationContext context) throws ConcurrentOperationException { DomainRouterVO router = _routerDao.findByNetworkConfiguration(config.getId()); @@ -112,11 +118,33 @@ public class DhcpElement extends AdapterBase implements NetworkElement { @Override public boolean applyRules(Network config, List rules) throws ResourceUnavailableException { - return true; + return false; } @Override public boolean applyIps(Network network, List ipAddress) throws ResourceUnavailableException { - return true; + return false; + } + + + @Override + public Provider getProvider() { + return Provider.DhcpServer; + } + + @Override + public Map> getCapabilities() { + return capabilities; + } + + private static Map> setCapabilities() { + Map> capabilities = new HashMap>(); + + capabilities.put(Service.Dns, null); + capabilities.put(Service.UserData, null); + capabilities.put(Service.Dhcp, null); + capabilities.put(Service.Gateway, null); + + return capabilities; } } diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 4b816b34b56..7c7819b2acc 100644 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -18,7 +18,9 @@ package com.cloud.network.element; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.ejb.Local; @@ -32,6 +34,9 @@ import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.LoadBalancerVO; import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; import com.cloud.network.NetworkManager; import com.cloud.network.PublicIpAddress; import com.cloud.network.dao.LoadBalancerDao; @@ -42,7 +47,6 @@ import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule.Purpose; -import com.cloud.network.service.Providers; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.offerings.dao.NetworkOfferingDao; @@ -65,6 +69,8 @@ import com.cloud.vm.dao.UserVmDao; public class VirtualRouterElement extends AdapterBase implements NetworkElement { private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class); + private static final Map> capabilities = setCapabilities(); + @Inject NetworkDao _networkConfigDao; @Inject NetworkManager _networkMgr; @Inject LoadBalancingRulesManager _lbMgr; @@ -76,10 +82,9 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement @Inject DataCenterDao _dataCenterDao; @Inject LoadBalancerDao _lbDao; - private boolean canHandle(GuestIpType ipType, DataCenter dc) { String provider = dc.getGatewayProvider(); - return (ipType == GuestIpType.Virtual && provider.equals(Providers.VirtualRouter)); + return (ipType == GuestIpType.Virtual && provider.equals(Provider.VirtualRouter.getName())); } @Override @@ -174,5 +179,49 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement return false; } } + + + @Override + public Provider getProvider() { + return Provider.VirtualRouter; + } + + @Override + public Map> getCapabilities() { + return capabilities; + } + + private static Map> setCapabilities() { + Map> capabilities = new HashMap>(); + + //Set capabilities for LB service + Map lbCapabilities = new HashMap(); + lbCapabilities.put(Capability.SupportedLBAlgorithms, "roundrobin,leastconn,sourceip"); + lbCapabilities.put(Capability.SupportedProtocols, "tcp, udp"); + + capabilities.put(Service.Lb, lbCapabilities); + + //Set capabilities for Firewall service + Map firewallCapabilities = new HashMap(); + firewallCapabilities.put(Capability.PortForwarding, "true"); + firewallCapabilities.put(Capability.StaticNat, "true"); + firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp"); + firewallCapabilities.put(Capability.MultipleIps, "true"); + firewallCapabilities.put(Capability.SupportedSourceNatTypes, "per account"); + + capabilities.put(Service.Firewall, firewallCapabilities); + + //Set capabilities for vpn + Map vpnCapabilities = new HashMap(); + vpnCapabilities.put(Capability.SupportedVpnTypes, "pptp,l2tp,ipsec"); + + capabilities.put(Service.Vpn, vpnCapabilities); + capabilities.put(Service.Dns, null); + capabilities.put(Service.UserData, null); + capabilities.put(Service.Dhcp, null); + capabilities.put(Service.Gateway, null); + + return capabilities; + } } diff --git a/server/src/com/cloud/network/guru/ControlNetworkGuru.java b/server/src/com/cloud/network/guru/ControlNetworkGuru.java index 74f935b2ecc..43436adc626 100644 --- a/server/src/com/cloud/network/guru/ControlNetworkGuru.java +++ b/server/src/com/cloud/network/guru/ControlNetworkGuru.java @@ -99,7 +99,7 @@ public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGu return; } - String ip = _dcDao.allocateLinkLocalIpAddress(dest.getDataCenter().getId(), dest.getPod().getId(), vm.getId(), context.getReservationId()); + String ip = _dcDao.allocateLinkLocalIpAddress(dest.getDataCenter().getId(), dest.getPod().getId(), nic.getId(), context.getReservationId()); nic.setIp4Address(ip); nic.setMacAddress(NetUtils.long2Mac(NetUtils.ip2Long(ip) | (14l << 40))); nic.setNetmask("255.255.0.0"); diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index 3bd44c1119c..82a46fff76d 100644 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -36,7 +36,9 @@ import com.cloud.dc.dao.VlanDao; import com.cloud.domain.dao.DomainDao; import com.cloud.event.EventTypes; import com.cloud.event.EventVO; +import com.cloud.event.UsageEventVO; import com.cloud.event.dao.EventDao; +import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.PermissionDeniedException; @@ -105,6 +107,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, @Inject AccountDao _accountDao; @Inject DomainDao _domainDao; @Inject NicDao _nicDao; + @Inject UsageEventDao _usageEventDao; @Override @DB public boolean assignToLoadBalancer(long loadBalancerId, List instanceIds) { @@ -241,6 +244,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, } _rulesDao.remove(lb.getId()); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_LOAD_BALANCER_DELETE, lb.getAccountId(), 0 , lb.getId(), null); + _usageEventDao.persist(usageEvent); s_logger.debug("Load balancer with id " + lb.getId() + " is removed successfully"); return true; } @@ -327,6 +332,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, String params = "id=" + newRule.getId() + "\ndcId=" + ipAddr.getDataCenterId(); event.setParameters(params); event.setLevel(EventVO.LEVEL_INFO); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_LOAD_BALANCER_CREATE, ipAddr.getAllocatedToAccountId(), ipAddr.getDataCenterId(), newRule.getId(), null); + _usageEventDao.persist(usageEvent); } _eventDao.persist(event); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 9f4b9de9bb1..a1b099906de 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -92,7 +92,9 @@ import com.cloud.domain.dao.DomainDao; import com.cloud.event.Event; import com.cloud.event.EventTypes; import com.cloud.event.EventVO; +import com.cloud.event.UsageEventVO; import com.cloud.event.dao.EventDao; +import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.DiscoveryException; @@ -211,6 +213,8 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag @Inject protected UserDao _userDao; @Inject protected ClusterDao _clusterDao; @Inject protected VirtualNetworkApplianceManager _routerMgr; + @Inject protected UsageEventDao _usageEventDao; + @Inject(adapter=StoragePoolAllocator.class) protected Adapters _storagePoolAllocators; @@ -696,6 +700,8 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag if (createdVolume.getPath() != null) { event.setDescription("Created volume: "+ createdVolume.getName() + " with size: " + sizeMB + " MB in pool: " + poolName + " from snapshot id: " + snapshotId); event.setLevel(EventVO.LEVEL_INFO); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), diskOfferingId, templateId , sizeMB); + _usageEventDao.persist(usageEvent); } else { details = "CreateVolume From Snapshot for snapshotId: " + snapshotId + " failed at the backend, reason " + details; @@ -830,6 +836,9 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag volume.setPodId(pod.getId()); volume.setState(Volume.State.Ready); _volsDao.persist(volume); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), diskOffering.getId(), null , dskCh.getSize()); + _usageEventDao.persist(usageEvent); + } txn.commit(); return volume; @@ -1906,6 +1915,8 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag event.setParameters(eventParams); event.setState(Event.State.Completed); _eventDao.persist(event); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), diskOffering.getId(), null , sizeMB); + _usageEventDao.persist(usageEvent); /* } else { event.setDescription("Unable to create a volume for " + volume); @@ -1943,6 +1954,9 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag event.setDescription("Volume " +volume.getName()+ " deleted"); event.setLevel(EventVO.LEVEL_INFO); _eventDao.persist(event); + + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), null, null , null); + _usageEventDao.persist(usageEvent); // Delete the recurring snapshot policies for this volume. _snapshotMgr.deletePoliciesForVolume(volumeId); @@ -2672,6 +2686,11 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag vol = _volsDao.persist(vol); + if(vm instanceof UserVm){ + long sizeMB = size / (1024 * 1024); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null , sizeMB); + _usageEventDao.persist(usageEvent); + } return toDiskProfile(vol, offering); } @@ -2704,6 +2723,11 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag vol = _volsDao.persist(vol); + if(vm instanceof UserVm){ + long sizeMB = vol.getSize() / (1024 * 1024); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), template.getId() , sizeMB); + _usageEventDao.persist(usageEvent); + } return toDiskProfile(vol, offering); } diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index fc83018b079..fd599f3a523 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -43,7 +43,9 @@ import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.event.EventTypes; import com.cloud.event.EventVO; +import com.cloud.event.UsageEventVO; import com.cloud.event.dao.EventDao; +import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.StorageUnavailableException; import com.cloud.host.Host; @@ -103,6 +105,9 @@ public class DownloadMonitorImpl implements DownloadMonitor { private AgentManager _agentMgr; @Inject ConfigurationDao _configDao; + + @Inject + private UsageEventDao _usageEventDao; private String _name; private Boolean _sslCopy = new Boolean(false); @@ -374,6 +379,8 @@ public class DownloadMonitorImpl implements DownloadMonitor { event.setParameters(eventParams); event.setLevel(EventVO.LEVEL_INFO); _eventDao.persist(event); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, template.getAccountId(), host.getDataCenterId(), template.getId(), template.getName(), null, null , size); + _usageEventDao.persist(usageEvent); } if (vmTemplateHost != null) { diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index a789192c28e..f6bbdff9f02 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -59,7 +59,9 @@ import com.cloud.domain.dao.DomainDao; import com.cloud.event.EventTypes; import com.cloud.event.EventUtils; import com.cloud.event.EventVO; +import com.cloud.event.UsageEventVO; import com.cloud.event.dao.EventDao; +import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; @@ -138,6 +140,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma @Inject protected AsyncJobManager _asyncMgr; @Inject protected AccountManager _accountMgr; @Inject protected ClusterDao _clusterDao; + @Inject private UsageEventDao _usageEventDao; String _name; private int _totalRetries; private int _pauseInterval; @@ -524,6 +527,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma event.setDescription("Backed up snapshot id: " + snapshotId + " to secondary for volume:" + volumeId); event.setLevel(EventVO.LEVEL_INFO); event.setParameters(eventParams); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), volume.getDataCenterId(), snapshotId, snapshotName, null, null, volume.getSize()); + _usageEventDao.persist(usageEvent); } else { @@ -769,6 +774,12 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma event.setLevel(success ? EventVO.LEVEL_INFO : EventVO.LEVEL_ERROR); _eventDao.persist(event); + if(success){ + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), volume.getDataCenterId(), snapshotId, snapshot.getName(), null, null, volume.getSize()); + _usageEventDao.persist(usageEvent); + } + + return success; } @@ -955,6 +966,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma event.setParameters(eventParams); event.setLevel(EventVO.LEVEL_INFO); _eventDao.persist(event); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), volume.getDataCenterId(), snapshot.getId(), snapshot.getName(), null, null, volume.getSize()); + _usageEventDao.persist(usageEvent); } } } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 70aa180e279..d28cf33a099 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -61,7 +61,9 @@ import com.cloud.event.Event; import com.cloud.event.EventTypes; import com.cloud.event.EventUtils; import com.cloud.event.EventVO; +import com.cloud.event.UsageEventVO; import com.cloud.event.dao.EventDao; +import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; @@ -127,6 +129,7 @@ import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; + @Local(value={TemplateManager.class, TemplateService.class}) public class TemplateManagerImpl implements TemplateManager, Manager, TemplateService { private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class); @@ -158,6 +161,7 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe @Inject AsyncJobManager _asyncMgr; @Inject UserVmManager _vmMgr; @Inject ConfigurationDao _configDao; + @Inject UsageEventDao _usageEventDao; protected SearchBuilder HostTemplateStatesSearch; @Override @@ -338,9 +342,11 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe } if((!url.toLowerCase().endsWith("vhd"))&&(!url.toLowerCase().endsWith("vhd.zip")) - &&(!url.toLowerCase().endsWith("vhd.bz2"))&&(!url.toLowerCase().endsWith("vhd.gz") + &&(!url.toLowerCase().endsWith("vhd.bz2"))&&(!url.toLowerCase().endsWith("vhd.gz")) &&(!url.toLowerCase().endsWith("qcow2"))&&(!url.toLowerCase().endsWith("qcow2.zip")) - &&(!url.toLowerCase().endsWith("qcow2.bz2"))&&(!url.toLowerCase().endsWith("qcow2.gz")))){ + &&(!url.toLowerCase().endsWith("qcow2.bz2"))&&(!url.toLowerCase().endsWith("qcow2.gz")) + &&(!url.toLowerCase().endsWith("ova"))&&(!url.toLowerCase().endsWith("ova.zip")) + &&(!url.toLowerCase().endsWith("ova.bz2"))&&(!url.toLowerCase().endsWith("ova.gz"))){ throw new ServerApiException(BaseCmd.PARAM_ERROR, "Please specify a valid "+format.toLowerCase()); } @@ -814,6 +820,8 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe _downloadMonitor.copyTemplate(vmTemplate, srcSecHost, dstSecHost); + UsageEventVO usageEvent = new UsageEventVO(copyEventType, account.getId(), destZoneId, templateId, null, null, null, srcTmpltHost.getSize()); + _usageEventDao.persist(usageEvent); saveEvent(userId, account.getId(), account.getDomainId(), copyEventType, copyEventDescription, EventVO.LEVEL_INFO, params, startEventId); return true; } @@ -960,6 +968,8 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe String zoneParams = params + "\ndcId=" + sZoneId; saveEvent(userId, account.getId(), account.getDomainId(), eventType, description + template.getName() + " succesfully deleted.", EventVO.LEVEL_INFO, zoneParams, 0); + UsageEventVO usageEvent = new UsageEventVO(eventType, account.getId(), sZoneId, templateId, null, null, null, null); + _usageEventDao.persist(usageEvent); } finally { if (lock != null) { _tmpltHostDao.releaseFromLockTable(lock.getId()); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index f00bc38d255..c520f4dd438 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -103,7 +103,9 @@ import com.cloud.event.Event; import com.cloud.event.EventTypes; import com.cloud.event.EventUtils; import com.cloud.event.EventVO; +import com.cloud.event.UsageEventVO; import com.cloud.event.dao.EventDao; +import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; @@ -252,6 +254,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager @Inject VirtualNetworkApplianceManager _routerMgr; @Inject NicDao _nicDao; @Inject RulesManager _rulesMgr; + @Inject UsageEventDao _usageEventDao; private IpAddrAllocator _IpAllocator; ScheduledExecutorService _executor = null; @@ -1106,7 +1109,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (!destroy(vm)) { return false; } - + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getName(), vm.getServiceOfferingId(), vm.getTemplateId(), null); + _usageEventDao.persist(usageEvent); cleanNetworkRules(userId, vmId); // Mark the VM's disks as destroyed @@ -1234,6 +1238,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } _eventDao.persist(event); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getName(), vm.getServiceOfferingId(), vm.getTemplateId(), null); + _usageEventDao.persist(usageEvent); txn.commit(); return _vmDao.findById(vmId); @@ -1384,6 +1390,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } _eventDao.persist(event); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_STOP, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getName(), vm.getServiceOfferingId(), vm.getTemplateId(), null); + _usageEventDao.persist(usageEvent); + if (_storageMgr.unshare(vm, null) == null) { s_logger.warn("Unable to set share to false for " + vm.toString()); } @@ -2527,6 +2536,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (s_logger.isDebugEnabled()) { s_logger.debug("Successfully allocated DB entry for " + vm); } + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_CREATE, accountId, dc.getId(), vm.getId(), vm.getName(), offering.getId(), template.getId(), null); + _usageEventDao.persist(usageEvent); return vm; } @@ -2718,6 +2729,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (status) { EventUtils.saveEvent(userId, vm.getAccountId(), EventTypes.EVENT_VM_DESTROY, "Successfully destroyed vm with id:"+vmId); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getName(), vm.getServiceOfferingId(), vm.getTemplateId(), null); + _usageEventDao.persist(usageEvent); return _vmDao.findById(vmId); } else { EventUtils.saveEvent(userId, vm.getAccountId(), EventTypes.EVENT_VM_DESTROY, "Failed to destroy vm with id:"+vmId); diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 559ad108b10..dcbee11b561 100644 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -51,6 +51,8 @@ import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.domain.dao.DomainDao; import com.cloud.event.EventTypes; import com.cloud.event.EventVO; +import com.cloud.event.UsageEventVO; +import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; @@ -74,6 +76,7 @@ import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; +import com.cloud.uservm.UserVm; import com.cloud.utils.Journal; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -113,6 +116,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster @Inject private DomainRouterDao _routerDao; @Inject private ConsoleProxyDao _consoleDao; @Inject private SecondaryStorageVmDao _secondaryDao; + @Inject private UsageEventDao _usageEventDao; @Inject(adapter=DeploymentPlanner.class) private Adapters _planners; @@ -431,6 +435,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster if (!stateTransitTo(vm, Event.OperationSucceeded, dest.getHost().getId())) { throw new CloudRuntimeException("Unable to transition to a new state."); } + if(vm instanceof UserVm){ + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_START, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getName(), vm.getServiceOfferingId(), vm.getTemplateId(), null); + _usageEventDao.persist(usageEvent); + } return vm; } s_logger.info("Unable to start VM on " + dest.getHost() + " due to " + answers[0].getDetails()); @@ -504,6 +512,9 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster stopped = answer.getResult(); if (!stopped) { throw new CloudRuntimeException("Unable to stop the virtual machine due to " + answer.getDetails()); + } else { + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_STOP, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getName(), vm.getServiceOfferingId(), vm.getTemplateId(), null); + _usageEventDao.persist(usageEvent); } } finally { if (!stopped) { diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 25c52b499d1..7282e3b603a 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -91,6 +91,7 @@ DROP TABLE IF EXISTS `cloud`.`load_balancing_ip_map`; DROP TABLE IF EXISTS `cloud`.`load_balancing_rules`; DROP TABLE IF EXISTS `cloud`.`port_forwarding_rules`; DROP TABLE IF EXISTS `cloud`.`firewall_rules`; +DROP TABLE IF EXISTS `cloud`.`usage_event`; CREATE TABLE `cloud`.`op_it_work` ( `id` char(40) COMMENT 'id', @@ -1252,4 +1253,18 @@ CREATE TABLE `cloud`.`instance_group_vm_map` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `cloud`.`usage_event` ( + `id` bigint unsigned NOT NULL auto_increment, + `type` varchar(32) NOT NULL, + `account_id` bigint unsigned NOT NULL, + `created` datetime NOT NULL, + `zone_id` bigint unsigned NOT NULL, + `resource_id` bigint unsigned, + `resource_name` varchar(255), + `offering_id` bigint unsigned, + `template_id` bigint unsigned, + `size` bigint unsigned, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + SET foreign_key_checks = 1; diff --git a/setup/db/templates.sql b/setup/db/templates.sql index fc6c439cb36..85c30039da6 100644 --- a/setup/db/templates.sql +++ b/setup/db/templates.sql @@ -13,7 +13,7 @@ INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, VALUES (7, 'centos53-x64', 'centos53-x64', 1, now(), 'builtin', 0, 64, 1, 'http://download.cloud.com/releases/2.2.0/CentOS5.3-x86_64.ova', 'f6f881b7f2292948d8494db837fe0f47', 0, 'centos53-x64', 'OVA', 12, 1, 1, 'VMware'); INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (8, 'routing-8', 'SystemVM Template (VMWare)', 0, now(), 'system', 0, 32, 1, 'http://download.cloud.com/releases/2.2.0/systemvm.vmdk.bz2', '7ebe04f68583f30064d187069faf7b0f', 0, 'SystemVM Template VMWare', 'OVA', 15, 0, 1, 'VMware'); + VALUES (8, 'routing-8', 'SystemVM Template (VMWare)', 0, now(), 'system', 0, 32, 1, 'http://download.cloud.com/releases/2.2.0/systemvm.ova', 'ee3dc55e94e23a0490310bb78cf8cc76', 0, 'SystemVM Template VMWare', 'OVA', 15, 0, 1, 'VMware'); INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (1, 'CentOS'); INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (2, 'Debian'); diff --git a/ui/css/main.css b/ui/css/main.css index 62298f2301c..d087d4e97f6 100644 --- a/ui/css/main.css +++ b/ui/css/main.css @@ -3494,8 +3494,9 @@ a:hover.search_button { height:auto; float:left; position:absolute; - background:#414141 repeat top left; - border:1px solid #CCC; + background:#444444 repeat top left; + border-bottom:1px solid #666; + border-left:1px solid #666; top:17px; right:0; margin:0; @@ -3517,7 +3518,7 @@ a:hover.search_button { height:auto; float:left; text-align:left; - background:#414141 repeat-x top left; + background:#444444 repeat-x top left; color:#CCC; font-size:11px; font-weight:normal; diff --git a/ui/index.jsp b/ui/index.jsp index ddd949d87ea..9180d44bdc0 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -374,7 +374,8 @@ - + +
diff --git a/ui/jsp/network.jsp b/ui/jsp/network.jsp index 494921f77f5..fbd63801b0e 100644 --- a/ui/jsp/network.jsp +++ b/ui/jsp/network.jsp @@ -46,7 +46,7 @@
Title
-