diff --git a/api/src/com/cloud/event/EventCategory.java b/api/src/com/cloud/event/EventCategory.java new file mode 100644 index 00000000000..cee6529b550 --- /dev/null +++ b/api/src/com/cloud/event/EventCategory.java @@ -0,0 +1,55 @@ +/* + * 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.event; + +import java.util.ArrayList; +import java.util.List; + +public class EventCategory { + private static List eventCategories = new ArrayList(); + private String eventCategoryName; + + public EventCategory(String categoryName) { + this.eventCategoryName = categoryName; + eventCategories.add(this); + } + + public String getName() { + return eventCategoryName; + } + + public static List listAllEventCategories() { + return eventCategories; + } + + public static EventCategory getEventCategory(String categoryName) { + for (EventCategory category : eventCategories) { + if (category.getName().equalsIgnoreCase(categoryName)) { + return category; + } + } + return null; + } + + public static final EventCategory ACTION_EVENT = new EventCategory("ActionEvent"); + public static final EventCategory ALERT_EVENT = new EventCategory("AlertEvent"); + public static final EventCategory USAGE_EVENT = new EventCategory("UsageEvent"); + public static final EventCategory RESOURCE_STATE_CHANGE_EVENT = new EventCategory("ResourceStateEvent"); +} diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index d666c1e4130..0dd97cb438c 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -16,7 +16,41 @@ // under the License. package com.cloud.event; +import com.cloud.configuration.Configuration; +import com.cloud.dc.DataCenter; +import com.cloud.dc.Pod; +import com.cloud.dc.StorageNetworkIpRange; +import com.cloud.dc.Vlan; +import com.cloud.domain.Domain; +import com.cloud.host.Host; +import com.cloud.network.*; +import com.cloud.network.as.*; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.rules.LoadBalancer; +import com.cloud.network.rules.StaticNat; +import com.cloud.network.security.SecurityGroup; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRoute; +import com.cloud.network.vpc.Vpc; +import com.cloud.offering.DiskOffering; +import com.cloud.offering.NetworkOffering; +import com.cloud.offering.ServiceOffering; +import com.cloud.projects.Project; +import com.cloud.storage.Snapshot; +import com.cloud.storage.Volume; +import com.cloud.template.VirtualMachineTemplate; +import com.cloud.user.Account; +import com.cloud.user.User; +import com.cloud.vm.VirtualMachine; + +import java.util.HashMap; +import java.util.Map; + public class EventTypes { + + //map of Event and corresponding entity for which Event is applicable + private static Map entityEventDetails = null; + // VM Events public static final String EVENT_VM_CREATE = "VM.CREATE"; public static final String EVENT_VM_DESTROY = "VM.DESTROY"; @@ -319,10 +353,323 @@ public class EventTypes { public static final String EVENT_AUTOSCALEVMGROUP_UPDATE = "AUTOSCALEVMGROUP.UPDATE"; public static final String EVENT_AUTOSCALEVMGROUP_ENABLE = "AUTOSCALEVMGROUP.ENABLE"; public static final String EVENT_AUTOSCALEVMGROUP_DISABLE = "AUTOSCALEVMGROUP.DISABLE"; - + + public static final String EVENT_BAREMETAL_DHCP_SERVER_ADD = "PHYSICAL.DHCP.ADD"; public static final String EVENT_BAREMETAL_DHCP_SERVER_DELETE = "PHYSICAL.DHCP.DELETE"; - public static final String EVENT_BAREMETAL_PXE_SERVER_ADD = "PHYSICAL.PXE.ADD"; public static final String EVENT_BAREMETAL_PXE_SERVER_DELETE = "PHYSICAL.PXE.DELETE"; + + static { + + // TODO: need a way to force author adding event types to declare the entity details as well, with out braking + // current ActionEvent annotation semantics + + entityEventDetails = new HashMap(); + + entityEventDetails.put(EVENT_VM_CREATE, VirtualMachine.class.getName()); + entityEventDetails.put(EVENT_VM_DESTROY, VirtualMachine.class.getName()); + entityEventDetails.put(EVENT_VM_START, VirtualMachine.class.getName()); + entityEventDetails.put(EVENT_VM_STOP, VirtualMachine.class.getName()); + entityEventDetails.put(EVENT_VM_REBOOT, VirtualMachine.class.getName()); + entityEventDetails.put(EVENT_VM_UPDATE, VirtualMachine.class.getName()); + entityEventDetails.put(EVENT_VM_UPGRADE, VirtualMachine.class.getName()); + entityEventDetails.put(EVENT_VM_RESETPASSWORD, VirtualMachine.class.getName()); + entityEventDetails.put(EVENT_VM_MIGRATE, VirtualMachine.class.getName()); + entityEventDetails.put(EVENT_VM_MOVE, VirtualMachine.class.getName()); + entityEventDetails.put(EVENT_VM_RESTORE, VirtualMachine.class.getName()); + + entityEventDetails.put(EVENT_ROUTER_CREATE, VirtualRouter.class.getName()); + entityEventDetails.put(EVENT_ROUTER_DESTROY, VirtualRouter.class.getName()); + entityEventDetails.put(EVENT_ROUTER_START, VirtualRouter.class.getName()); + entityEventDetails.put(EVENT_ROUTER_STOP, VirtualRouter.class.getName()); + entityEventDetails.put(EVENT_ROUTER_REBOOT, VirtualRouter.class.getName()); + entityEventDetails.put(EVENT_ROUTER_HA, VirtualRouter.class.getName()); + entityEventDetails.put(EVENT_ROUTER_UPGRADE, VirtualRouter.class.getName()); + + entityEventDetails.put(EVENT_PROXY_CREATE, "ConsoleProxy"); + entityEventDetails.put(EVENT_PROXY_DESTROY, "ConsoleProxy"); + entityEventDetails.put(EVENT_PROXY_START, "ConsoleProxy"); + entityEventDetails.put(EVENT_PROXY_STOP, "ConsoleProxy"); + entityEventDetails.put(EVENT_PROXY_REBOOT, "ConsoleProxy"); + entityEventDetails.put(EVENT_ROUTER_HA, "ConsoleProxy"); + entityEventDetails.put(EVENT_PROXY_HA, "ConsoleProxy"); + + entityEventDetails.put(EVENT_VNC_CONNECT, "VNC"); + entityEventDetails.put(EVENT_VNC_DISCONNECT, "VNC"); + + // Network Events + entityEventDetails.put(EVENT_NETWORK_CREATE, Network.class.getName()); + entityEventDetails.put(EVENT_NETWORK_DELETE, Network.class.getName()); + entityEventDetails.put(EVENT_NETWORK_UPDATE, Network.class.getName()); + entityEventDetails.put(EVENT_NETWORK_RESTART, Network.class.getName()); + entityEventDetails.put(EVENT_NET_IP_ASSIGN, PublicIpAddress.class.getName()); + entityEventDetails.put(EVENT_NET_IP_RELEASE, PublicIpAddress.class.getName()); + entityEventDetails.put(EVENT_NET_RULE_ADD, Network.class.getName()); + entityEventDetails.put(EVENT_NET_RULE_DELETE, Network.class.getName()); + entityEventDetails.put(EVENT_NET_RULE_MODIFY, Network.class.getName()); + entityEventDetails.put(EVENT_FIREWALL_OPEN, Network.class.getName()); + entityEventDetails.put(EVENT_FIREWALL_CLOSE, Network.class.getName()); + + // Load Balancers + entityEventDetails.put(EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, LoadBalancer.class.getName()); + entityEventDetails.put(EVENT_REMOVE_FROM_LOAD_BALANCER_RULE, LoadBalancer.class.getName()); + entityEventDetails.put(EVENT_LOAD_BALANCER_CREATE, LoadBalancer.class.getName()); + entityEventDetails.put(EVENT_LOAD_BALANCER_DELETE, LoadBalancer.class.getName()); + entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_CREATE, LoadBalancer.class.getName()); + entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_DELETE, LoadBalancer.class.getName()); + entityEventDetails.put(EVENT_LOAD_BALANCER_UPDATE, LoadBalancer.class.getName()); + + // Account events + entityEventDetails.put(EVENT_ACCOUNT_DISABLE, Account.class.getName()); + entityEventDetails.put(EVENT_ACCOUNT_CREATE, Account.class.getName()); + entityEventDetails.put(EVENT_ACCOUNT_DELETE, Account.class.getName()); + entityEventDetails.put(EVENT_ACCOUNT_MARK_DEFAULT_ZONE, Account.class.getName()); + + // UserVO Events + entityEventDetails.put(EVENT_USER_LOGIN, User.class.getName()); + entityEventDetails.put(EVENT_USER_LOGOUT, User.class.getName()); + entityEventDetails.put(EVENT_USER_CREATE, User.class.getName()); + entityEventDetails.put(EVENT_USER_DELETE, User.class.getName()); + entityEventDetails.put(EVENT_USER_DISABLE, User.class.getName()); + entityEventDetails.put(EVENT_USER_UPDATE, User.class.getName()); + entityEventDetails.put(EVENT_USER_ENABLE, User.class.getName()); + entityEventDetails.put(EVENT_USER_LOCK, User.class.getName()); + + // Template Events + entityEventDetails.put(EVENT_TEMPLATE_CREATE, VirtualMachineTemplate.class.getName()); + entityEventDetails.put(EVENT_TEMPLATE_DELETE, VirtualMachineTemplate.class.getName()); + entityEventDetails.put(EVENT_TEMPLATE_UPDATE, VirtualMachineTemplate.class.getName()); + entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_START, VirtualMachineTemplate.class.getName()); + entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_SUCCESS, VirtualMachineTemplate.class.getName()); + entityEventDetails.put(EVENT_TEMPLATE_DOWNLOAD_FAILED, VirtualMachineTemplate.class.getName()); + entityEventDetails.put(EVENT_TEMPLATE_COPY, VirtualMachineTemplate.class.getName()); + entityEventDetails.put(EVENT_TEMPLATE_EXTRACT, VirtualMachineTemplate.class.getName()); + entityEventDetails.put(EVENT_TEMPLATE_UPLOAD, VirtualMachineTemplate.class.getName()); + entityEventDetails.put(EVENT_TEMPLATE_CLEANUP, VirtualMachineTemplate.class.getName()); + + // Volume Events + entityEventDetails.put(EVENT_VOLUME_CREATE, Volume.class.getName()); + entityEventDetails.put(EVENT_VOLUME_DELETE, Volume.class.getName()); + entityEventDetails.put(EVENT_VOLUME_ATTACH, Volume.class.getName()); + entityEventDetails.put(EVENT_VOLUME_DETACH, Volume.class.getName()); + entityEventDetails.put(EVENT_VOLUME_EXTRACT, Volume.class.getName()); + entityEventDetails.put(EVENT_VOLUME_UPLOAD, Volume.class.getName()); + entityEventDetails.put(EVENT_VOLUME_MIGRATE, Volume.class.getName()); + entityEventDetails.put(EVENT_VOLUME_RESIZE, Volume.class.getName()); + + // Domains + entityEventDetails.put(EVENT_DOMAIN_CREATE, Domain.class.getName()); + entityEventDetails.put(EVENT_DOMAIN_DELETE, Domain.class.getName()); + entityEventDetails.put(EVENT_DOMAIN_UPDATE, Domain.class.getName()); + + // Snapshots + entityEventDetails.put(EVENT_SNAPSHOT_CREATE, Snapshot.class.getName()); + entityEventDetails.put(EVENT_SNAPSHOT_DELETE, Snapshot.class.getName()); + entityEventDetails.put(EVENT_SNAPSHOT_POLICY_CREATE, Snapshot.class.getName()); + entityEventDetails.put(EVENT_SNAPSHOT_POLICY_UPDATE, Snapshot.class.getName()); + entityEventDetails.put(EVENT_SNAPSHOT_POLICY_DELETE, Snapshot.class.getName()); + + // ISO + entityEventDetails.put(EVENT_ISO_CREATE, "Iso"); + entityEventDetails.put(EVENT_ISO_DELETE, "Iso"); + entityEventDetails.put(EVENT_ISO_COPY, "Iso"); + entityEventDetails.put(EVENT_ISO_ATTACH, "Iso"); + entityEventDetails.put(EVENT_ISO_DETACH, "Iso"); + entityEventDetails.put(EVENT_ISO_EXTRACT, "Iso"); + entityEventDetails.put(EVENT_ISO_UPLOAD, "Iso"); + + // SSVM + entityEventDetails.put(EVENT_SSVM_CREATE, "SecondaryStorageVm"); + entityEventDetails.put(EVENT_SSVM_DESTROY, "SecondaryStorageVm"); + entityEventDetails.put(EVENT_SSVM_START, "SecondaryStorageVm"); + entityEventDetails.put(EVENT_SSVM_STOP, "SecondaryStorageVm"); + entityEventDetails.put(EVENT_SSVM_REBOOT, "SecondaryStorageVm"); + entityEventDetails.put(EVENT_SSVM_HA, "SecondaryStorageVm"); + + // Service Offerings + entityEventDetails.put(EVENT_SERVICE_OFFERING_CREATE, ServiceOffering.class.getName()); + entityEventDetails.put(EVENT_SERVICE_OFFERING_EDIT, ServiceOffering.class.getName()); + entityEventDetails.put(EVENT_SERVICE_OFFERING_DELETE, ServiceOffering.class.getName()); + + // Disk Offerings + entityEventDetails.put(EVENT_DISK_OFFERING_CREATE, DiskOffering.class.getName()); + entityEventDetails.put(EVENT_DISK_OFFERING_EDIT, DiskOffering.class.getName()); + entityEventDetails.put(EVENT_DISK_OFFERING_DELETE, DiskOffering.class.getName()); + + // Network offerings + entityEventDetails.put(EVENT_NETWORK_OFFERING_CREATE, NetworkOffering.class.getName()); + entityEventDetails.put(EVENT_NETWORK_OFFERING_ASSIGN, NetworkOffering.class.getName()); + entityEventDetails.put(EVENT_NETWORK_OFFERING_EDIT, NetworkOffering.class.getName()); + entityEventDetails.put(EVENT_NETWORK_OFFERING_REMOVE, NetworkOffering.class.getName()); + entityEventDetails.put(EVENT_NETWORK_OFFERING_DELETE, NetworkOffering.class.getName()); + + // Pods + entityEventDetails.put(EVENT_POD_CREATE, Pod.class.getName()); + entityEventDetails.put(EVENT_POD_EDIT, Pod.class.getName()); + entityEventDetails.put(EVENT_POD_DELETE, Pod.class.getName()); + + // Zones + entityEventDetails.put(EVENT_ZONE_CREATE, DataCenter.class.getName()); + entityEventDetails.put(EVENT_ZONE_EDIT, DataCenter.class.getName()); + entityEventDetails.put(EVENT_ZONE_DELETE, DataCenter.class.getName()); + + // VLANs/IP ranges + entityEventDetails.put(EVENT_VLAN_IP_RANGE_CREATE, Vlan.class.getName()); + entityEventDetails.put(EVENT_VLAN_IP_RANGE_DELETE,Vlan.class.getName()); + + entityEventDetails.put(EVENT_STORAGE_IP_RANGE_CREATE, StorageNetworkIpRange.class.getName()); + entityEventDetails.put(EVENT_STORAGE_IP_RANGE_DELETE, StorageNetworkIpRange.class.getName()); + entityEventDetails.put(EVENT_STORAGE_IP_RANGE_UPDATE, StorageNetworkIpRange.class.getName()); + + // Configuration Table + entityEventDetails.put(EVENT_CONFIGURATION_VALUE_EDIT, Configuration.class.getName()); + + // Security Groups + entityEventDetails.put(EVENT_SECURITY_GROUP_AUTHORIZE_INGRESS, SecurityGroup.class.getName()); + entityEventDetails.put(EVENT_SECURITY_GROUP_REVOKE_INGRESS, SecurityGroup.class.getName()); + entityEventDetails.put(EVENT_SECURITY_GROUP_AUTHORIZE_EGRESS, SecurityGroup.class.getName()); + entityEventDetails.put(EVENT_SECURITY_GROUP_REVOKE_EGRESS, SecurityGroup.class.getName()); + entityEventDetails.put(EVENT_SECURITY_GROUP_CREATE, SecurityGroup.class.getName()); + entityEventDetails.put(EVENT_SECURITY_GROUP_DELETE, SecurityGroup.class.getName()); + entityEventDetails.put(EVENT_SECURITY_GROUP_ASSIGN, SecurityGroup.class.getName()); + entityEventDetails.put(EVENT_SECURITY_GROUP_REMOVE, SecurityGroup.class.getName()); + + // Host + entityEventDetails.put(EVENT_HOST_RECONNECT, Host.class.getName()); + + // Maintenance + entityEventDetails.put(EVENT_MAINTENANCE_CANCEL, Host.class.getName()); + entityEventDetails.put(EVENT_MAINTENANCE_CANCEL_PRIMARY_STORAGE, Host.class.getName()); + entityEventDetails.put(EVENT_MAINTENANCE_PREPARE, Host.class.getName()); + entityEventDetails.put(EVENT_MAINTENANCE_PREPARE_PRIMARY_STORAGE, Host.class.getName()); + + // VPN + entityEventDetails.put(EVENT_REMOTE_ACCESS_VPN_CREATE, RemoteAccessVpn.class.getName()); + entityEventDetails.put(EVENT_REMOTE_ACCESS_VPN_DESTROY, RemoteAccessVpn.class.getName()); + entityEventDetails.put(EVENT_VPN_USER_ADD, RemoteAccessVpn.class.getName()); + entityEventDetails.put(EVENT_VPN_USER_REMOVE, RemoteAccessVpn.class.getName()); + entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_CREATE, RemoteAccessVpn.class.getName()); + entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_DELETE, RemoteAccessVpn.class.getName()); + entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE, RemoteAccessVpn.class.getName()); + entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE, RemoteAccessVpn.class.getName()); + entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE, RemoteAccessVpn.class.getName()); + entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_CREATE, RemoteAccessVpn.class.getName()); + entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_DELETE, RemoteAccessVpn.class.getName()); + entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_RESET, RemoteAccessVpn.class.getName()); + + // Custom certificates + entityEventDetails.put(EVENT_UPLOAD_CUSTOM_CERTIFICATE, "Certificate"); + + // OneToOnenat + entityEventDetails.put(EVENT_ENABLE_STATIC_NAT, StaticNat.class.getName()); + entityEventDetails.put(EVENT_DISABLE_STATIC_NAT, StaticNat.class.getName()); + + entityEventDetails.put(EVENT_ZONE_VLAN_ASSIGN,Vlan.class.getName()); + entityEventDetails.put(EVENT_ZONE_VLAN_RELEASE,Vlan.class.getName()); + + // Projects + entityEventDetails.put(EVENT_PROJECT_CREATE, Project.class.getName()); + entityEventDetails.put(EVENT_PROJECT_UPDATE, Project.class.getName()); + entityEventDetails.put(EVENT_PROJECT_DELETE, Project.class.getName()); + entityEventDetails.put(EVENT_PROJECT_ACTIVATE, Project.class.getName()); + entityEventDetails.put(EVENT_PROJECT_SUSPEND, Project.class.getName()); + entityEventDetails.put(EVENT_PROJECT_ACCOUNT_ADD, Project.class.getName()); + entityEventDetails.put(EVENT_PROJECT_INVITATION_UPDATE, Project.class.getName()); + entityEventDetails.put(EVENT_PROJECT_INVITATION_REMOVE, Project.class.getName()); + entityEventDetails.put(EVENT_PROJECT_ACCOUNT_REMOVE, Project.class.getName()); + + // Network as a Service + entityEventDetails.put(EVENT_NETWORK_ELEMENT_CONFIGURE,Network.class.getName()); + + // Physical Network Events + entityEventDetails.put(EVENT_PHYSICAL_NETWORK_CREATE, PhysicalNetwork.class.getName()); + entityEventDetails.put(EVENT_PHYSICAL_NETWORK_DELETE, PhysicalNetwork.class.getName()); + entityEventDetails.put(EVENT_PHYSICAL_NETWORK_UPDATE, PhysicalNetwork.class.getName()); + + // Physical Network Service Provider Events + entityEventDetails.put(EVENT_SERVICE_PROVIDER_CREATE, PhysicalNetworkServiceProvider.class.getName()); + entityEventDetails.put(EVENT_SERVICE_PROVIDER_DELETE, PhysicalNetworkServiceProvider.class.getName()); + entityEventDetails.put(EVENT_SERVICE_PROVIDER_UPDATE, PhysicalNetworkServiceProvider.class.getName()); + + // Physical Network TrafficType Events + entityEventDetails.put(EVENT_TRAFFIC_TYPE_CREATE, PhysicalNetworkTrafficType.class.getName()); + entityEventDetails.put(EVENT_TRAFFIC_TYPE_DELETE, PhysicalNetworkTrafficType.class.getName()); + entityEventDetails.put(EVENT_TRAFFIC_TYPE_UPDATE, PhysicalNetworkTrafficType.class.getName()); + + // external network device events + entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_ADD, PhysicalNetwork.class.getName()); + entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_DELETE, PhysicalNetwork.class.getName()); + entityEventDetails.put(EVENT_EXTERNAL_LB_DEVICE_CONFIGURE, PhysicalNetwork.class.getName()); + + // external switch management device events (E.g.: Cisco Nexus 1000v Virtual Supervisor Module. + entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ADD, "Nexus1000v"); + entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DELETE, "Nexus1000v"); + entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_CONFIGURE, "Nexus1000v"); + entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ENABLE, "Nexus1000v"); + entityEventDetails.put(EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DISABLE, "Nexus1000v"); + + + entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_ADD, PhysicalNetwork.class.getName()); + entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_DELETE, PhysicalNetwork.class.getName()); + entityEventDetails.put(EVENT_EXTERNAL_FIREWALL_DEVICE_CONFIGURE, PhysicalNetwork.class.getName()); + + // VPC + entityEventDetails.put(EVENT_VPC_CREATE, Vpc.class.getName()); + entityEventDetails.put(EVENT_VPC_UPDATE, Vpc.class.getName()); + entityEventDetails.put(EVENT_VPC_DELETE, Vpc.class.getName()); + entityEventDetails.put(EVENT_VPC_RESTART, Vpc.class.getName()); + + // VPC offerings + entityEventDetails.put(EVENT_VPC_OFFERING_CREATE, Vpc.class.getName()); + entityEventDetails.put(EVENT_VPC_OFFERING_UPDATE, Vpc.class.getName()); + entityEventDetails.put(EVENT_VPC_OFFERING_DELETE, Vpc.class.getName()); + + // Private gateway + entityEventDetails.put(EVENT_PRIVATE_GATEWAY_CREATE, PrivateGateway.class.getName()); + entityEventDetails.put(EVENT_PRIVATE_GATEWAY_DELETE, PrivateGateway.class.getName()); + + // Static routes + entityEventDetails.put(EVENT_STATIC_ROUTE_CREATE, StaticRoute.class.getName()); + entityEventDetails.put(EVENT_STATIC_ROUTE_DELETE, StaticRoute.class.getName()); + + // tag related events + entityEventDetails.put(EVENT_TAGS_CREATE, "Tag"); + entityEventDetails.put(EVENT_TAGS_DELETE, "tag"); + + // external network device events + entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_ADD, "NvpController"); + entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_DELETE, "NvpController"); + entityEventDetails.put(EVENT_EXTERNAL_NVP_CONTROLLER_CONFIGURE, "NvpController"); + + // AutoScale + entityEventDetails.put(EVENT_COUNTER_CREATE, AutoScaleCounter.class.getName()); + entityEventDetails.put(EVENT_COUNTER_DELETE, AutoScaleCounter.class.getName()); + entityEventDetails.put(EVENT_CONDITION_CREATE, Condition.class.getName()); + entityEventDetails.put(EVENT_CONDITION_DELETE, Condition.class.getName()); + entityEventDetails.put(EVENT_AUTOSCALEPOLICY_CREATE, AutoScalePolicy.class.getName()); + entityEventDetails.put(EVENT_AUTOSCALEPOLICY_UPDATE, AutoScalePolicy.class.getName()); + entityEventDetails.put(EVENT_AUTOSCALEPOLICY_DELETE, AutoScalePolicy.class.getName()); + entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_CREATE, AutoScaleVmProfile.class.getName()); + entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_DELETE, AutoScaleVmProfile.class.getName()); + entityEventDetails.put(EVENT_AUTOSCALEVMPROFILE_UPDATE, AutoScaleVmProfile.class.getName()); + entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_CREATE, AutoScaleVmGroup.class.getName()); + entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DELETE, AutoScaleVmGroup.class.getName()); + entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_UPDATE, AutoScaleVmGroup.class.getName()); + entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_ENABLE, AutoScaleVmGroup.class.getName()); + entityEventDetails.put(EVENT_AUTOSCALEVMGROUP_DISABLE, AutoScaleVmGroup.class.getName()); + } + + public static String getEntityForEvent (String eventName) { + String entityClassName = entityEventDetails.get(eventName); + if (entityClassName == null || entityClassName.isEmpty()) { + return null; + } + int index = entityClassName.lastIndexOf("."); + String entityName = entityClassName; + if (index != -1) { + entityName = entityClassName.substring(index+1); + } + return entityName; + } } diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 413b6d96665..1dbb327155e 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -16,26 +16,25 @@ // under the License. package com.cloud.network; -import org.apache.cloudstack.acl.ControlledEntity; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; -import com.cloud.utils.fsm.FiniteState; -import com.cloud.utils.fsm.StateMachine; +import com.cloud.utils.fsm.StateMachine2; +import com.cloud.utils.fsm.StateObject; +import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; import java.net.URI; import java.util.ArrayList; import java.util.List; -import java.util.Set; /** * owned by an account. */ -public interface Network extends ControlledEntity, InternalIdentity, Identity { +public interface Network extends ControlledEntity, StateObject, InternalIdentity, Identity { - public enum GuestType { + public enum GuestType { Shared, Isolated } @@ -204,7 +203,8 @@ public interface Network extends ControlledEntity, InternalIdentity, Identity { OperationFailed; } - enum State implements FiniteState { + public enum State { + Allocated("Indicates the network configuration is in allocated but not setup"), Setup("Indicates the network configuration is setup"), Implementing("Indicates the network configuration is being implemented"), @@ -212,39 +212,8 @@ public interface Network extends ControlledEntity, InternalIdentity, Identity { Shutdown("Indicates the network configuration is being destroyed"), Destroy("Indicates that the network is destroyed"); + protected static final StateMachine2 s_fsm = new StateMachine2(); - @Override - public StateMachine getStateMachine() { - return s_fsm; - } - - @Override - public State getNextState(Event event) { - return s_fsm.getNextState(this, event); - } - - @Override - public List getFromStates(Event event) { - return s_fsm.getFromStates(this, event); - } - - @Override - public Set getPossibleEvents() { - return s_fsm.getPossibleEvents(this); - } - - String _description; - - @Override - public String getDescription() { - return _description; - } - - private State(String description) { - _description = description; - } - - private static StateMachine s_fsm = new StateMachine(); static { s_fsm.addTransition(State.Allocated, Event.ImplementNetwork, State.Implementing); s_fsm.addTransition(State.Implementing, Event.OperationSucceeded, State.Implemented); @@ -253,6 +222,15 @@ public interface Network extends ControlledEntity, InternalIdentity, Identity { s_fsm.addTransition(State.Shutdown, Event.OperationSucceeded, State.Allocated); s_fsm.addTransition(State.Shutdown, Event.OperationFailed, State.Implemented); } + + public static StateMachine2 getStateMachine() { + return s_fsm; + } + + String _description; + private State(String description) { + _description = description; + } } String getName(); diff --git a/api/src/com/cloud/storage/Snapshot.java b/api/src/com/cloud/storage/Snapshot.java index 99bdee6bea9..2e2965ae149 100644 --- a/api/src/com/cloud/storage/Snapshot.java +++ b/api/src/com/cloud/storage/Snapshot.java @@ -16,14 +16,16 @@ // under the License. package com.cloud.storage; -import java.util.Date; - -import org.apache.cloudstack.acl.ControlledEntity; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.utils.fsm.StateMachine2; +import com.cloud.utils.fsm.StateObject; +import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; -public interface Snapshot extends ControlledEntity, Identity, InternalIdentity { +import java.util.Date; + +public interface Snapshot extends ControlledEntity, Identity, InternalIdentity, StateObject { public enum Type { MANUAL, RECURRING, @@ -51,13 +53,29 @@ public interface Snapshot extends ControlledEntity, Identity, InternalIdentity { } } - public enum Status { + public enum State { Creating, CreatedOnPrimary, BackingUp, BackedUp, Error; + private final static StateMachine2 s_fsm = new StateMachine2(); + + public static StateMachine2 getStateMachine() { + return s_fsm; + } + + static { + s_fsm.addTransition(null, Event.CreateRequested, Creating); + s_fsm.addTransition(Creating, Event.OperationSucceeded, CreatedOnPrimary); + s_fsm.addTransition(Creating, Event.OperationNotPerformed, BackedUp); + s_fsm.addTransition(Creating, Event.OperationFailed, Error); + s_fsm.addTransition(CreatedOnPrimary, Event.BackupToSecondary, BackingUp); + s_fsm.addTransition(BackingUp, Event.OperationSucceeded, BackedUp); + s_fsm.addTransition(BackingUp, Event.OperationFailed, Error); + } + public String toString() { return this.name(); } @@ -67,6 +85,15 @@ public interface Snapshot extends ControlledEntity, Identity, InternalIdentity { } } + enum Event { + CreateRequested, + OperationNotPerformed, + BackupToSecondary, + BackedupToSecondary, + OperationSucceeded, + OperationFailed + } + public static final long MANUAL_POLICY_ID = 0L; long getAccountId(); @@ -81,7 +108,7 @@ public interface Snapshot extends ControlledEntity, Identity, InternalIdentity { Type getType(); - Status getStatus(); + State getState(); HypervisorType getHypervisorType(); diff --git a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java index 8ea0d7fb87f..58b7cf1525f 100644 --- a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java @@ -16,16 +16,16 @@ // under the License. package org.apache.cloudstack.api.response; -import java.util.Date; -import java.util.List; - -import org.apache.cloudstack.api.ApiConstants; import com.cloud.serializer.Param; import com.cloud.storage.Snapshot; import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; import org.apache.cloudstack.api.EntityReference; +import java.util.Date; +import java.util.List; + @EntityReference(value=Snapshot.class) @SuppressWarnings("unused") public class SnapshotResponse extends BaseResponse implements ControlledEntityResponse { @@ -81,7 +81,7 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe @SerializedName(ApiConstants.STATE) @Param(description = "the state of the snapshot. BackedUp means that snapshot is ready to be used; Creating - the snapshot is being allocated on the primary storage; BackingUp - the snapshot is being backed up on secondary storage") - private Snapshot.Status state; + private Snapshot.State state; @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with snapshot", responseObject = ResourceTagResponse.class) private List tags; @@ -149,7 +149,7 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe this.intervalType = intervalType; } - public void setState(Snapshot.Status state) { + public void setState(Snapshot.State state) { this.state = state; } diff --git a/client/pom.xml b/client/pom.xml index 7ebe50c48f9..63ec2ef6686 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -116,6 +116,11 @@ cloud-plugin-host-allocator-random ${project.version} + + org.apache.cloudstack + cloud-mom-rabbitmq + ${project.version} + mysql mysql-connector-java diff --git a/core/src/com/cloud/storage/SnapshotVO.java b/core/src/com/cloud/storage/SnapshotVO.java index e5e36504ea6..c1c5f214d77 100644 --- a/core/src/com/cloud/storage/SnapshotVO.java +++ b/core/src/com/cloud/storage/SnapshotVO.java @@ -16,23 +16,13 @@ // under the License. package com.cloud.storage; -import java.util.Date; -import java.util.UUID; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; - -import org.apache.cloudstack.api.Identity; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.db.GenericDao; import com.google.gson.annotations.Expose; -import org.apache.cloudstack.api.InternalIdentity; + +import javax.persistence.*; +import java.util.Date; +import java.util.UUID; @Entity @Table(name="snapshots") @@ -69,7 +59,7 @@ public class SnapshotVO implements Snapshot { @Expose @Column(name="status", updatable = true, nullable=false) @Enumerated(value=EnumType.STRING) - private Status status; + private State status; @Column(name="snapshot_type") short snapshotType; @@ -127,7 +117,7 @@ public class SnapshotVO implements Snapshot { this.snapshotType = snapshotType; this.typeDescription = typeDescription; this.size = size; - this.status = Status.Creating; + this.status = State.Creating; this.prevSnapshotId = 0; this.hypervisorType = hypervisorType; this.version = "2.2"; @@ -252,11 +242,11 @@ public class SnapshotVO implements Snapshot { } @Override - public Status getStatus() { + public State getState() { return status; } - public void setStatus(Status status) { + public void setStatus(State status) { this.status = status; } diff --git a/framework/events/pom.xml b/framework/events/pom.xml new file mode 100644 index 00000000000..ef812e5a014 --- /dev/null +++ b/framework/events/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + cloud-framework-events + Apache CloudStack Event Notification Framework + + org.apache.cloudstack + cloudstack-framework + 4.1.0-SNAPSHOT + ../pom.xml + + + + org.apache.cloudstack + cloud-utils + ${project.version} + + + com.google.code.gson + gson + ${cs.gson.version} + + + + install + src + test + + diff --git a/framework/events/src/org/apache/cloudstack/framework/events/Event.java b/framework/events/src/org/apache/cloudstack/framework/events/Event.java new file mode 100644 index 00000000000..eb6f48de3b8 --- /dev/null +++ b/framework/events/src/org/apache/cloudstack/framework/events/Event.java @@ -0,0 +1,94 @@ +/* + * 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.framework.events; + +import com.google.gson.Gson; + +public class Event { + + String eventCategory; + String eventType; + String eventSource; + String resourceType; + String resourceUUID; + String description; + + public Event(String eventSource, String eventCategory, String eventType, String resourceType, + String resourceUUID) { + this.eventCategory = eventCategory; + this.eventType = eventType; + this.eventSource = eventSource; + this.resourceType = resourceType; + this.resourceUUID = resourceUUID; + } + + public String getEventCategory() { + return eventCategory; + } + + public void setEventCategory(String category) { + eventCategory = category; + } + + public String getEventType() { + return eventType; + } + + public void setEventType(String type) { + eventType = type; + } + + public String getEventSource() { + return eventSource; + } + + void setEventSource(String source) { + eventSource = source; + } + + public String getDescription() { + return description; + } + + public void setDescription (Object message) { + Gson gson = new Gson(); + this.description = gson.toJson(message).toString(); + } + + public void setDescription(String description) { + this.description = description; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public void setResourceUUID(String uuid) { + this.resourceUUID = uuid; + } + + public String getResourceUUID () { + return resourceUUID; + } +} \ No newline at end of file diff --git a/framework/events/src/org/apache/cloudstack/framework/events/EventBus.java b/framework/events/src/org/apache/cloudstack/framework/events/EventBus.java new file mode 100644 index 00000000000..c16ee6f96f4 --- /dev/null +++ b/framework/events/src/org/apache/cloudstack/framework/events/EventBus.java @@ -0,0 +1,55 @@ +/* + * 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.framework.events; + +import com.cloud.utils.component.Adapter; + +import java.util.UUID; + +/** + * Interface to publish and subscribe to CloudStack events + * + */ +public interface EventBus extends Adapter{ + + /** + * publish an event on to the event bus + * + * @param event event that needs to be published on the event bus + */ + void publish(Event event) throws EventBusException; + + /** + * subscribe to events that matches specified event topics + * + * @param topic defines category and type of the events being subscribed to + * @param subscriber subscriber that intends to receive event notification + * @return UUID returns the subscription ID + */ + UUID subscribe(EventTopic topic, EventSubscriber subscriber) throws EventBusException; + + /** + * unsubscribe to events of a category and a type + * + * @param subscriber subscriber that intends to unsubscribe from the event notification + */ + void unsubscribe(UUID subscriberId, EventSubscriber subscriber) throws EventBusException; + +} diff --git a/framework/events/src/org/apache/cloudstack/framework/events/EventBusException.java b/framework/events/src/org/apache/cloudstack/framework/events/EventBusException.java new file mode 100644 index 00000000000..5654ba04804 --- /dev/null +++ b/framework/events/src/org/apache/cloudstack/framework/events/EventBusException.java @@ -0,0 +1,26 @@ +/* + * 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.framework.events; + +public class EventBusException extends Exception{ + public EventBusException (String msg) { + super(msg); + } +} diff --git a/framework/events/src/org/apache/cloudstack/framework/events/EventSubscriber.java b/framework/events/src/org/apache/cloudstack/framework/events/EventSubscriber.java new file mode 100644 index 00000000000..b1c30c21587 --- /dev/null +++ b/framework/events/src/org/apache/cloudstack/framework/events/EventSubscriber.java @@ -0,0 +1,30 @@ +/* + * 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/LICENSE2.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.framework.events; + +public interface EventSubscriber { + + /** + * Callback method. EventBus calls this method on occurrence of subscribed event + * + * @param event details of the event + */ + void onEvent(Event event); +} diff --git a/framework/events/src/org/apache/cloudstack/framework/events/EventTopic.java b/framework/events/src/org/apache/cloudstack/framework/events/EventTopic.java new file mode 100644 index 00000000000..19b727d4519 --- /dev/null +++ b/framework/events/src/org/apache/cloudstack/framework/events/EventTopic.java @@ -0,0 +1,57 @@ +/* + * 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.framework.events; + +public class EventTopic { + + String eventCategory; + String eventType; + String resourceType; + String resourceUUID; + String eventSource; + + public EventTopic(String eventCategory, String eventType, String resourceType, String resourceUUID, String eventSource) { + this.eventCategory = eventCategory; + this.eventType = eventType; + this.resourceType = resourceType; + this.resourceUUID = resourceUUID; + this.eventSource = eventSource; + } + + public String getEventCategory() { + return eventCategory; + } + + public String getEventType() { + return eventType; + } + + public String getResourceType() { + return resourceType; + } + + public String getEventSource() { + return eventSource; + } + + public String getResourceUUID() { + return resourceUUID; + } +} diff --git a/framework/pom.xml b/framework/pom.xml new file mode 100644 index 00000000000..81e091605b9 --- /dev/null +++ b/framework/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + cloudstack-framework + Apache CloudStack framework POM + pom + + org.apache.cloudstack + cloudstack + 4.1.0-SNAPSHOT + + + install + + + events + + diff --git a/plugins/event-bus/rabbitmq/pom.xml b/plugins/event-bus/rabbitmq/pom.xml new file mode 100644 index 00000000000..6a47983a9b5 --- /dev/null +++ b/plugins/event-bus/rabbitmq/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + cloud-mom-rabbitmq + Apache CloudStack Plugin - RabbitMQ Event Bus + + org.apache.cloudstack + cloudstack-plugins + 4.1.0-SNAPSHOT + ../../pom.xml + + + + com.rabbitmq + amqp-client + 2.8.7 + + + org.apache.cloudstack + cloud-framework-events + ${project.version} + + + + install + src + + diff --git a/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java b/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java new file mode 100644 index 00000000000..3a06c42d277 --- /dev/null +++ b/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java @@ -0,0 +1,555 @@ +/* + * 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.mom.rabbitmq; + +import com.rabbitmq.client.*; +import org.apache.cloudstack.framework.events.*; +import org.apache.log4j.Logger; + +import com.cloud.utils.Ternary; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.io.IOException; +import java.net.ConnectException; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@Local(value=EventBus.class) +public class RabbitMQEventBus implements EventBus { + + // details of AMQP server + private static String _amqpHost; + private static Integer _port; + private static String _username; + private static String _password; + + // AMQP exchange name where all CloudStack events will be published + private static String _amqpExchangeName; + + // hashmap to book keep the registered subscribers + private static ConcurrentHashMap> _subscribers; + + // connection to AMQP server, + private static Connection _connection=null; + + // AMQP server should consider messages acknowledged once delivered if _autoAck is true + private static boolean _autoAck = true; + + private ExecutorService executorService; + private String _name; + private static DisconnectHandler disconnectHandler; + private static Integer _retryInterval; + private static final Logger s_logger = Logger.getLogger(RabbitMQEventBus.class); + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + + _amqpHost = (String) params.get("server"); + if (_amqpHost == null || _amqpHost.isEmpty()) { + throw new ConfigurationException("Unable to get the AMQP server details"); + } + + _username = (String) params.get("username"); + if (_username == null || _username.isEmpty()) { + throw new ConfigurationException("Unable to get the username details"); + } + + _password = (String) params.get("password"); + if (_password == null || _password.isEmpty()) { + throw new ConfigurationException("Unable to get the password details"); + } + + _amqpExchangeName = (String) params.get("exchangename"); + if (_amqpExchangeName == null || _amqpExchangeName.isEmpty()) { + throw new ConfigurationException("Unable to get the _exchange details on the AMQP server"); + } + + try { + String portStr = (String) params.get("port"); + if (portStr == null || portStr.isEmpty()) { + throw new ConfigurationException("Unable to get the port details of AMQP server"); + } + _port = Integer.parseInt(portStr); + + String retryIntervalStr = (String) params.get("retryinterval"); + if (retryIntervalStr == null || retryIntervalStr.isEmpty()) { + // default to 10s to try out reconnect + retryIntervalStr = "10000"; + } + _retryInterval = Integer.parseInt(retryIntervalStr); + } catch (NumberFormatException e) { + throw new ConfigurationException("Invalid port number/retry interval"); + } + + _subscribers = new ConcurrentHashMap>(); + + executorService = Executors.newCachedThreadPool(); + disconnectHandler = new DisconnectHandler(); + _name = name; + return true; + } + + /** Call to subscribe to interested set of events + * + * @param topic defines category and type of the events being subscribed to + * @param subscriber subscriber that intends to receive event notification + * @return UUID that represents the subscription with event bus + * @throws EventBusException + */ + @Override + public UUID subscribe(EventTopic topic, EventSubscriber subscriber) throws EventBusException { + + if (subscriber == null || topic == null) { + throw new EventBusException("Invalid EventSubscriber/EventTopic object passed."); + } + + // create a UUID, that will be used for managing subscriptions and also used as queue name + // for on the queue used for the subscriber on the AMQP broker + UUID queueId = UUID.randomUUID(); + String queueName = queueId.toString(); + + try { + String bindingKey = createBindingKey(topic); + + // store the subscriber details before creating channel + _subscribers.put(queueName, new Ternary(bindingKey, null, subscriber)); + + // create a channel dedicated for this subscription + Connection connection = getConnection(); + Channel channel = createChannel(connection); + + // create a queue and bind it to the exchange with binding key formed from event topic + createExchange(channel, _amqpExchangeName); + channel.queueDeclare(queueName, false, false, false, null); + channel.queueBind(queueName, _amqpExchangeName, bindingKey); + + // register a callback handler to receive the events that a subscriber subscribed to + channel.basicConsume(queueName, _autoAck, queueName, + new DefaultConsumer(channel) { + @Override + public void handleDelivery(String queueName, + Envelope envelope, + AMQP.BasicProperties properties, + byte[] body) + throws IOException { + Ternary queueDetails = _subscribers.get(queueName); + if (queueDetails != null) { + EventSubscriber subscriber = queueDetails.third(); + String routingKey = envelope.getRoutingKey(); + String eventSource = getEventSourceFromRoutingKey(routingKey); + String eventCategory = getEventCategoryFromRoutingKey(routingKey); + String eventType = getEventTypeFromRoutingKey(routingKey); + String resourceType = getResourceTypeFromRoutingKey(routingKey); + String resourceUUID = getResourceUUIDFromRoutingKey(routingKey); + Event event = new Event(eventSource, eventCategory, eventType, + resourceType, resourceUUID); + event.setDescription(new String(body)); + + // deliver the event to call back object provided by subscriber + subscriber.onEvent(event); + } + } + } + ); + + // update the channel details for the subscription + Ternary queueDetails = _subscribers.get(queueName); + queueDetails.second(channel); + _subscribers.put(queueName, queueDetails); + + } catch (AlreadyClosedException closedException) { + s_logger.warn("Connection to AMQP service is lost. Subscription:" + queueName + + " will be active after reconnection"); + } catch (ConnectException connectException) { + s_logger.warn("Connection to AMQP service is lost. Subscription:" + queueName + + " will be active after reconnection"); + } catch (Exception e) { + throw new EventBusException("Failed to subscribe to event due to " + e.getMessage()); + } + + return queueId; + } + + @Override + public void unsubscribe(UUID subscriberId, EventSubscriber subscriber) throws EventBusException { + try { + String classname = subscriber.getClass().getName(); + String queueName = UUID.nameUUIDFromBytes(classname.getBytes()).toString(); + Ternary queueDetails = _subscribers.get(queueName); + Channel channel = queueDetails.second(); + channel.basicCancel(queueName); + _subscribers.remove(queueName, queueDetails); + } catch (Exception e) { + throw new EventBusException("Failed to unsubscribe from event bus due to " + e.getMessage()); + } + } + + // publish event on to the exchange created on AMQP server + @Override + public void publish(Event event) throws EventBusException { + + String routingKey = createRoutingKey(event); + String eventDescription = event.getDescription(); + + try { + Connection connection = getConnection(); + Channel channel = createChannel(connection); + createExchange(channel, _amqpExchangeName); + publishEventToExchange(channel, _amqpExchangeName, routingKey, eventDescription); + channel.close(); + } catch (AlreadyClosedException e) { + closeConnection(); + throw new EventBusException("Failed to publish event to message broker as connection to AMQP broker in lost"); + } catch (Exception e) { + throw new EventBusException("Failed to publish event to message broker due to " + e.getMessage()); + } + } + + /** creates a routing key from the event details. + * created routing key will be used while publishing the message to exchange on AMQP server + */ + private String createRoutingKey(Event event) { + + StringBuilder routingKey = new StringBuilder(); + + String eventSource = replaceNullWithWildcard(event.getEventSource()); + eventSource = eventSource.replace(".", "-"); + + String eventCategory = replaceNullWithWildcard(event.getEventCategory()); + eventCategory = eventCategory.replace(".", "-"); + + String eventType = replaceNullWithWildcard(event.getEventType()); + eventType = eventType.replace(".", "-"); + + String resourceType = replaceNullWithWildcard(event.getResourceType()); + resourceType = resourceType.replace(".", "-"); + + String resourceUuid = replaceNullWithWildcard(event.getResourceUUID()); + resourceUuid = resourceUuid.replace(".", "-"); + + // routing key will be of format: eventSource.eventCategory.eventType.resourceType.resourceUuid + routingKey.append(eventSource); + routingKey.append("."); + routingKey.append(eventCategory); + routingKey.append("."); + routingKey.append(eventType); + routingKey.append("."); + routingKey.append(resourceType); + routingKey.append("."); + routingKey.append(resourceUuid); + + return routingKey.toString(); + } + + /** creates a binding key from the event topic that subscriber specified + * binding key will be used to bind the queue created for subscriber to exchange on AMQP server + */ + private String createBindingKey(EventTopic topic) { + + StringBuilder bindingKey = new StringBuilder(); + + String eventSource = replaceNullWithWildcard(topic.getEventSource()); + eventSource = eventSource.replace(".", "-"); + + String eventCategory = replaceNullWithWildcard(topic.getEventCategory()); + eventCategory = eventCategory.replace(".", "-"); + + String eventType = replaceNullWithWildcard(topic.getEventType()); + eventType = eventType.replace(".", "-"); + + String resourceType = replaceNullWithWildcard(topic.getResourceType()); + resourceType = resourceType.replace(".", "-"); + + String resourceUuid = replaceNullWithWildcard(topic.getResourceUUID()); + resourceUuid = resourceUuid.replace(".", "-"); + + // binding key will be of format: eventSource.eventCategory.eventType.resourceType.resourceUuid + bindingKey.append(eventSource); + bindingKey.append("."); + bindingKey.append(eventCategory); + bindingKey.append("."); + bindingKey.append(eventType); + bindingKey.append("."); + bindingKey.append(resourceType); + bindingKey.append("."); + bindingKey.append(resourceUuid); + + return bindingKey.toString(); + } + + private synchronized Connection getConnection() throws Exception { + if (_connection == null) { + try { + return createConnection(); + } catch (Exception e) { + s_logger.error("Failed to create a connection to AMQP server due to " + e.getMessage()); + throw e; + } + } else { + return _connection; + } + } + + private synchronized Connection createConnection() throws Exception { + try { + ConnectionFactory factory = new ConnectionFactory(); + factory.setUsername(_username); + factory.setPassword(_password); + factory.setVirtualHost("/"); + factory.setHost(_amqpHost); + factory.setPort(_port); + Connection connection = factory.newConnection(); + connection.addShutdownListener(disconnectHandler); + _connection = connection; + return _connection; + } catch (Exception e) { + throw e; + } + } + + private synchronized void closeConnection() { + try { + if (_connection != null) { + _connection.close(); + } + } catch (Exception e) { + s_logger.warn("Failed to close connection to AMQP server due to " + e.getMessage()); + } + _connection = null; + } + + private synchronized void abortConnection () { + if (_connection == null) + return; + + try { + _connection.abort(); + } catch (Exception e) { + s_logger.warn("Failed to abort connection due to " + e.getMessage()); + } + _connection = null; + } + + private String replaceNullWithWildcard(String key) { + if (key == null || key.isEmpty()) { + return "*"; + } else { + return key; + } + } + + private Channel createChannel(Connection connection) throws Exception { + try { + return connection.createChannel(); + } catch (java.io.IOException exception) { + s_logger.warn("Failed to create a channel due to " + exception.getMessage()); + throw exception; + } + } + + private void createExchange(Channel channel, String exchangeName) throws Exception { + try { + channel.exchangeDeclare(exchangeName, "topic", true); + } catch (java.io.IOException exception) { + s_logger.error("Failed to create exchange" + exchangeName + " on RabbitMQ server"); + throw exception; + } + } + + private void publishEventToExchange(Channel channel, String exchangeName, + String routingKey, String eventDescription) throws Exception { + try { + byte[] messageBodyBytes = eventDescription.getBytes(); + channel.basicPublish(exchangeName, routingKey, MessageProperties.PERSISTENT_TEXT_PLAIN, messageBodyBytes); + } catch (Exception e) { + s_logger.error("Failed to publish event " + routingKey + " on exchange " + exchangeName + + " of message broker due to " + e.getMessage()); + throw e; + } + } + + private String getEventCategoryFromRoutingKey(String routingKey) { + String[] keyParts = routingKey.split("\\."); + return keyParts[1]; + } + + private String getEventTypeFromRoutingKey(String routingKey) { + String[] keyParts = routingKey.split("\\."); + return keyParts[2]; + } + + private String getEventSourceFromRoutingKey(String routingKey) { + String[] keyParts = routingKey.split("\\."); + return keyParts[0]; + } + + private String getResourceTypeFromRoutingKey(String routingKey) { + String[] keyParts = routingKey.split("\\."); + return keyParts[3]; + } + + private String getResourceUUIDFromRoutingKey(String routingKey) { + String[] keyParts = routingKey.split("\\."); + return keyParts[4]; + } + + @Override + public String getName() { + return _name; + } + + @Override + public boolean start() { + ReconnectionTask reconnect = new ReconnectionTask(); // initiate connection to AMQP server + executorService.submit(reconnect); + return true; + } + + @Override + public boolean stop() { + + if (_connection.isOpen()) { + for (String subscriberId : _subscribers.keySet()) { + Ternary subscriberDetails = _subscribers.get(subscriberId); + Channel channel = subscriberDetails.second(); + String queueName = subscriberId; + try { + channel.queueDelete(queueName); + channel.abort(); + } catch (IOException ioe) { + s_logger.warn("Failed to delete queue: " + queueName + " on AMQP server due to " + ioe.getMessage() ); + } + } + } + + closeConnection(); + return true; + } + + // logic to deal with loss of connection to AMQP server + private class DisconnectHandler implements ShutdownListener { + + @Override + public void shutdownCompleted(ShutdownSignalException shutdownSignalException) { + if (!shutdownSignalException.isInitiatedByApplication()) { + + for (String subscriberId : _subscribers.keySet()) { + Ternary subscriberDetails = _subscribers.get(subscriberId); + subscriberDetails.second(null); + _subscribers.put(subscriberId, subscriberDetails); + } + + abortConnection(); // disconnected to AMQP server, so abort the connection and channels + s_logger.warn("Connection has been shutdown by AMQP server. Attempting to reconnect."); + + // initiate re-connect process + ReconnectionTask reconnect = new ReconnectionTask(); + executorService.submit(reconnect); + } + } + } + + // retry logic to connect back to AMQP server after loss of connection + private class ReconnectionTask implements Runnable { + + boolean connected = false; + Connection connection = null; + + public void run() { + + while (!connected) { + try { + Thread.sleep(_retryInterval); + } catch (InterruptedException ie) { + // ignore timer interrupts + } + + try { + try { + connection = createConnection(); + connected = true; + } catch (IOException ie) { + continue; // can't establish connection to AMQP server yet, so continue + } + + // prepare consumer on AMQP server for each of subscriber + for (String subscriberId : _subscribers.keySet()) { + Ternary subscriberDetails = _subscribers.get(subscriberId); + String bindingKey = subscriberDetails.first(); + EventSubscriber subscriber = subscriberDetails.third(); + + /** create a queue with subscriber ID as queue name and bind it to the exchange + * with binding key formed from event topic + */ + Channel channel = createChannel(connection); + createExchange(channel, _amqpExchangeName); + channel.queueDeclare(subscriberId, false, false, false, null); + channel.queueBind(subscriberId, _amqpExchangeName, bindingKey); + + // register a callback handler to receive the events that a subscriber subscribed to + channel.basicConsume(subscriberId, _autoAck, subscriberId, + new DefaultConsumer(channel) { + @Override + public void handleDelivery(String queueName, + Envelope envelope, + AMQP.BasicProperties properties, + byte[] body) + throws IOException { + + Ternary subscriberDetails + = _subscribers.get(queueName); // queue name == subscriber ID + + if (subscriberDetails != null) { + EventSubscriber subscriber = subscriberDetails.third(); + String routingKey = envelope.getRoutingKey(); + String eventSource = getEventSourceFromRoutingKey(routingKey); + String eventCategory = getEventCategoryFromRoutingKey(routingKey); + String eventType = getEventTypeFromRoutingKey(routingKey); + String resourceType = getResourceTypeFromRoutingKey(routingKey); + String resourceUUID = getResourceUUIDFromRoutingKey(routingKey); + + // create event object from the message details obtained from AMQP server + Event event = new Event(eventSource, eventCategory, eventType, + resourceType, resourceUUID); + event.setDescription(new String(body)); + + // deliver the event to call back object provided by subscriber + subscriber.onEvent(event); + } + } + } + ); + + // update the channel details for the subscription + subscriberDetails.second(channel); + _subscribers.put(subscriberId, subscriberDetails); + } + } catch (Exception e) { + s_logger.warn("Failed to recreate queues and binding for the subscribers due to " + e.getMessage()); + } + } + return; + } + } +} \ No newline at end of file diff --git a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java index 30a11294051..2104322a869 100644 --- a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java +++ b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java @@ -18,6 +18,7 @@ package com.cloud.network.guru; import javax.ejb.Local; +import com.cloud.event.ActionEventUtils; import org.apache.log4j.Logger; import com.cloud.dc.DataCenter; @@ -25,7 +26,6 @@ import com.cloud.dc.DataCenter.NetworkType; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.event.EventTypes; -import com.cloud.event.EventUtils; import com.cloud.event.EventVO; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; import com.cloud.network.Network; @@ -95,7 +95,7 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru { throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a part of network " + network + " implement ", DataCenter.class, dcId); } implemented.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vnet)); - EventUtils.saveEvent(UserContext.current().getCallerUserId(), network.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: "+vnet+ " Network Id: "+network.getId(), 0); + ActionEventUtils.onCompletedActionEvent(UserContext.current().getCallerUserId(), network.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnet + " Network Id: " + network.getId(), 0); } else { implemented.setBroadcastUri(network.getBroadcastUri()); } diff --git a/plugins/pom.xml b/plugins/pom.xml index c5b6e58e1bb..f91c6eed58b 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -41,6 +41,7 @@ hypervisors/ovm hypervisors/xen hypervisors/kvm + event-bus/rabbitmq hypervisors/simulator hypervisors/baremetal network-elements/elastic-loadbalancer diff --git a/pom.xml b/pom.xml index 35d6520ce6b..59feef5b2f4 100644 --- a/pom.xml +++ b/pom.xml @@ -163,6 +163,7 @@ patches client test + framework diff --git a/server/pom.xml b/server/pom.xml index 4c3ba6f9e76..ef1b68a1a53 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -80,6 +80,11 @@ tests test + + org.apache.cloudstack + cloud-framework-events + ${project.version} + install diff --git a/server/src/com/cloud/alert/AlertManagerImpl.java b/server/src/com/cloud/alert/AlertManagerImpl.java index a4c0facc97d..1a93f97a704 100755 --- a/server/src/com/cloud/alert/AlertManagerImpl.java +++ b/server/src/com/cloud/alert/AlertManagerImpl.java @@ -59,6 +59,7 @@ import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterIpAddressDao; import com.cloud.dc.dao.HostPodDao; +import com.cloud.event.AlertGenerator; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; @@ -260,6 +261,10 @@ public class AlertManagerImpl implements AlertManager { @Override public void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String body) { + + // publish alert + AlertGenerator.publishAlertOnEventBus(getAlertType(alertType), dataCenterId, podId, subject, body); + // TODO: queue up these messages and send them as one set of issues once a certain number of issues is reached? If that's the case, // shouldn't we have a type/severity as part of the API so that severe errors get sent right away? try { @@ -271,6 +276,65 @@ public class AlertManagerImpl implements AlertManager { } } + private String getAlertType(short alertType) { + if (alertType == ALERT_TYPE_MEMORY) { + return "ALERT.MEMORY"; + } else if (alertType == ALERT_TYPE_CPU) { + return "ALERT.MEMORY"; + } else if (alertType == ALERT_TYPE_STORAGE) { + return "ALERT.STORAGE"; + } else if (alertType == ALERT_TYPE_STORAGE_ALLOCATED) { + return "ALERT.STORAGE.ALLOCATED"; + } else if (alertType == ALERT_TYPE_VIRTUAL_NETWORK_PUBLIC_IP) { + return "ALERT.NETWORK.PUBLICIP"; + } else if (alertType == ALERT_TYPE_PRIVATE_IP) { + return "ALERT.NETWORK.PRIVATEIP"; + } else if (alertType == ALERT_TYPE_SECONDARY_STORAGE) { + return "ALERT.STORAGE.SECONDARY"; + } else if (alertType == ALERT_TYPE_HOST) { + return "ALERT.COMPUTE.HOST"; + } else if (alertType == ALERT_TYPE_USERVM) { + return "ALERT.USERVM"; + } else if (alertType == ALERT_TYPE_DOMAIN_ROUTER) { + return "ALERT.SERVICE.DOMAINROUTER"; + } else if (alertType == ALERT_TYPE_CONSOLE_PROXY) { + return "ALERT.SERVICE.CONSOLEPROXY"; + } else if (alertType == ALERT_TYPE_ROUTING) { + return "ALERT.NETWORK.ROUTING"; + } else if (alertType == ALERT_TYPE_STORAGE_MISC) { + return "ALERT.STORAGE.MISC"; + } else if (alertType == ALERT_TYPE_USAGE_SERVER) { + return "ALERT.USAGE"; + } else if (alertType == ALERT_TYPE_MANAGMENT_NODE) { + return "ALERT.MANAGEMENT"; + } else if (alertType == ALERT_TYPE_DOMAIN_ROUTER_MIGRATE) { + return "ALERT.NETWORK.DOMAINROUTERMIGRATE"; + } else if (alertType == ALERT_TYPE_CONSOLE_PROXY_MIGRATE) { + return "ALERT.SERVICE.CONSOLEPROXYMIGRATE"; + } else if (alertType == ALERT_TYPE_USERVM_MIGRATE) { + return "ALERT.USERVM.MIGRATE"; + } else if (alertType == ALERT_TYPE_VLAN) { + return "ALERT.NETWORK.VLAN"; + } else if (alertType == ALERT_TYPE_SSVM) { + return "ALERT.SERVICE.SSVM"; + } else if (alertType == ALERT_TYPE_USAGE_SERVER_RESULT) { + return "ALERT.USAGE.RESULT"; + } else if (alertType == ALERT_TYPE_STORAGE_DELETE) { + return "ALERT.STORAGE.DELETE"; + } else if (alertType == ALERT_TYPE_UPDATE_RESOURCE_COUNT) { + return "ALERT.RESOURCE.COUNT"; + } else if (alertType == ALERT_TYPE_USAGE_SANITY_RESULT) { + return "ALERT.USAGE.SANITY"; + } else if (alertType == ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP) { + return "ALERT.NETWORK.DIRECTPUBLICIP"; + } else if (alertType == ALERT_TYPE_LOCAL_STORAGE) { + return "ALERT.STORAGE.LOCAL"; + } else if (alertType == ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED) { + return "ALERT.RESOURCE.EXCEED"; + } + return "UNKNOWN"; + } + @Override @DB public void recalculateCapacity() { // FIXME: the right way to do this is to register a listener (see RouterStatsListener, VMSyncListener) diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 0b08b26cc32..143e2800db8 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -16,68 +16,8 @@ // under the License. package com.cloud.api; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.cloudstack.api.ApiConstants.HostDetails; -import org.apache.cloudstack.api.ApiConstants.VMDetails; -import org.apache.cloudstack.api.response.AccountResponse; -import org.apache.cloudstack.api.response.AsyncJobResponse; -import org.apache.cloudstack.api.response.DiskOfferingResponse; -import org.apache.cloudstack.api.response.DomainRouterResponse; -import org.apache.cloudstack.api.response.EventResponse; -import org.apache.cloudstack.api.response.HostResponse; -import org.apache.cloudstack.api.response.InstanceGroupResponse; -import org.apache.cloudstack.api.response.ProjectAccountResponse; -import org.apache.cloudstack.api.response.ProjectInvitationResponse; -import org.apache.cloudstack.api.response.ProjectResponse; -import org.apache.cloudstack.api.response.ResourceTagResponse; -import org.apache.cloudstack.api.response.SecurityGroupResponse; -import org.apache.cloudstack.api.response.ServiceOfferingResponse; -import org.apache.cloudstack.api.response.StoragePoolResponse; -import org.apache.cloudstack.api.response.UserResponse; -import org.apache.cloudstack.api.response.UserVmResponse; -import org.apache.cloudstack.api.response.VolumeResponse; -import org.apache.cloudstack.api.response.ZoneResponse; - -import com.cloud.api.query.dao.AccountJoinDao; -import com.cloud.api.query.dao.AsyncJobJoinDao; -import com.cloud.api.query.dao.DataCenterJoinDao; -import com.cloud.api.query.dao.DiskOfferingJoinDao; -import com.cloud.api.query.dao.DomainRouterJoinDao; -import com.cloud.api.query.dao.HostJoinDao; -import com.cloud.api.query.dao.InstanceGroupJoinDao; -import com.cloud.api.query.dao.ProjectAccountJoinDao; -import com.cloud.api.query.dao.ProjectInvitationJoinDao; -import com.cloud.api.query.dao.ProjectJoinDao; -import com.cloud.api.query.dao.ResourceTagJoinDao; -import com.cloud.api.query.dao.SecurityGroupJoinDao; -import com.cloud.api.query.dao.ServiceOfferingJoinDao; -import com.cloud.api.query.dao.StoragePoolJoinDao; -import com.cloud.api.query.dao.UserAccountJoinDao; -import com.cloud.api.query.dao.UserVmJoinDao; -import com.cloud.api.query.dao.VolumeJoinDao; -import com.cloud.api.query.vo.AccountJoinVO; -import com.cloud.api.query.vo.AsyncJobJoinVO; -import com.cloud.api.query.vo.DataCenterJoinVO; -import com.cloud.api.query.vo.DiskOfferingJoinVO; -import com.cloud.api.query.vo.DomainRouterJoinVO; -import com.cloud.api.query.vo.EventJoinVO; -import com.cloud.api.query.vo.HostJoinVO; -import com.cloud.api.query.vo.InstanceGroupJoinVO; -import com.cloud.api.query.vo.ProjectAccountJoinVO; -import com.cloud.api.query.vo.ProjectInvitationJoinVO; -import com.cloud.api.query.vo.ProjectJoinVO; -import com.cloud.api.query.vo.ResourceTagJoinVO; -import com.cloud.api.query.vo.SecurityGroupJoinVO; -import com.cloud.api.query.vo.ServiceOfferingJoinVO; -import com.cloud.api.query.vo.StoragePoolJoinVO; -import com.cloud.api.query.vo.UserAccountJoinVO; -import com.cloud.api.query.vo.UserVmJoinVO; -import com.cloud.api.query.vo.VolumeJoinVO; +import com.cloud.api.query.dao.*; +import com.cloud.api.query.vo.*; import com.cloud.async.AsyncJob; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobVO; @@ -89,18 +29,8 @@ import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationService; import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.AccountVlanMapVO; -import com.cloud.dc.ClusterVO; -import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.HostPodVO; -import com.cloud.dc.Vlan; -import com.cloud.dc.VlanVO; -import com.cloud.dc.dao.AccountVlanMapDao; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.HostPodDao; -import com.cloud.dc.dao.VlanDao; +import com.cloud.dc.*; +import com.cloud.dc.dao.*; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.Event; @@ -112,65 +42,23 @@ import com.cloud.host.HostStats; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.IPAddressVO; -import com.cloud.network.IpAddress; -import com.cloud.network.LoadBalancerVO; -import com.cloud.network.Network; +import com.cloud.network.*; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; -import com.cloud.network.NetworkDomainVO; -import com.cloud.network.NetworkManager; -import com.cloud.network.NetworkModel; -import com.cloud.network.NetworkProfile; -import com.cloud.network.NetworkRuleConfigVO; -import com.cloud.network.NetworkVO; -import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.PhysicalNetworkVO; -import com.cloud.network.Site2SiteVpnGatewayVO; -import com.cloud.network.Site2SiteCustomerGatewayVO; import com.cloud.network.Networks.TrafficType; -import com.cloud.network.as.AutoScalePolicy; -import com.cloud.network.as.AutoScalePolicyConditionMapVO; -import com.cloud.network.as.AutoScalePolicyVO; -import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO; -import com.cloud.network.as.AutoScaleVmGroupVO; -import com.cloud.network.as.AutoScaleVmProfileVO; -import com.cloud.network.as.ConditionVO; -import com.cloud.network.as.CounterVO; -import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao; -import com.cloud.network.as.dao.AutoScalePolicyDao; -import com.cloud.network.as.dao.AutoScaleVmGroupDao; -import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao; -import com.cloud.network.as.dao.AutoScaleVmProfileDao; -import com.cloud.network.as.dao.ConditionDao; -import com.cloud.network.as.dao.CounterDao; -import com.cloud.network.dao.FirewallRulesCidrsDao; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.LoadBalancerDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.PhysicalNetworkDao; -import com.cloud.network.dao.NetworkDomainDao; -import com.cloud.network.dao.NetworkRuleConfigDao; -import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; -import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; -import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao; -import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO; -import com.cloud.network.dao.Site2SiteVpnGatewayDao; -import com.cloud.network.dao.Site2SiteCustomerGatewayDao; +import com.cloud.network.as.*; +import com.cloud.network.as.dao.*; +import com.cloud.network.dao.*; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.SecurityGroupVO; import com.cloud.network.security.dao.SecurityGroupDao; -import com.cloud.network.vpc.StaticRouteVO; -import com.cloud.network.vpc.VpcGatewayVO; -import com.cloud.network.vpc.VpcManager; -import com.cloud.network.vpc.VpcOffering; -import com.cloud.network.vpc.VpcVO; +import com.cloud.network.vpc.*; import com.cloud.network.vpc.dao.StaticRouteDao; +import com.cloud.network.vpc.dao.VpcDao; import com.cloud.network.vpc.dao.VpcGatewayDao; import com.cloud.network.vpc.dao.VpcOfferingDao; import com.cloud.offering.DiskOffering; @@ -183,57 +71,16 @@ import com.cloud.projects.ProjectAccount; import com.cloud.projects.ProjectInvitation; import com.cloud.projects.ProjectService; import com.cloud.resource.ResourceManager; -import com.cloud.server.Criteria; -import com.cloud.server.ManagementServer; -import com.cloud.server.ResourceTag; +import com.cloud.server.*; import com.cloud.server.ResourceTag.TaggedResourceType; -import com.cloud.server.StatsCollector; -import com.cloud.server.TaggedResourceService; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.GuestOS; -import com.cloud.storage.GuestOSCategoryVO; -import com.cloud.storage.Snapshot; -import com.cloud.storage.SnapshotVO; +import com.cloud.storage.*; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.StorageStats; -import com.cloud.storage.UploadVO; -import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateS3VO; -import com.cloud.storage.VMTemplateSwiftVO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; import com.cloud.storage.Volume.Type; -import com.cloud.storage.VolumeHostVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.GuestOSCategoryDao; -import com.cloud.storage.dao.GuestOSDao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.SnapshotPolicyDao; -import com.cloud.storage.dao.StoragePoolDao; -import com.cloud.storage.dao.UploadDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateDetailsDao; -import com.cloud.storage.dao.VMTemplateHostDao; -import com.cloud.storage.dao.VMTemplateS3Dao; -import com.cloud.storage.dao.VMTemplateSwiftDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.storage.dao.*; import com.cloud.storage.snapshot.SnapshotPolicy; -import com.cloud.user.Account; -import com.cloud.user.AccountDetailsDao; -import com.cloud.user.AccountVO; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.SSHKeyPairVO; -import com.cloud.user.User; -import com.cloud.user.UserAccount; -import com.cloud.user.UserStatisticsVO; -import com.cloud.user.UserVO; +import com.cloud.user.*; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.SSHKeyPairDao; import com.cloud.user.dao.UserDao; @@ -242,23 +89,13 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.component.ComponentLocator; -import com.cloud.vm.ConsoleProxyVO; -import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.InstanceGroup; -import com.cloud.vm.InstanceGroupVO; -import com.cloud.vm.NicProfile; -import com.cloud.vm.UserVmDetailVO; -import com.cloud.vm.UserVmManager; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VmStats; -import com.cloud.vm.dao.ConsoleProxyDao; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.dao.UserVmDetailsDao; -import com.cloud.vm.dao.VMInstanceDao; -import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.vm.*; +import com.cloud.vm.dao.*; +import org.apache.cloudstack.api.ApiConstants.HostDetails; +import org.apache.cloudstack.api.ApiConstants.VMDetails; +import org.apache.cloudstack.api.response.*; + +import java.util.*; public class ApiDBUtils { private static ManagementServer _ms; @@ -699,7 +536,7 @@ public class ApiDBUtils { public static Snapshot findSnapshotById(long snapshotId) { SnapshotVO snapshot = _snapshotDao.findById(snapshotId); - if (snapshot != null && snapshot.getRemoved() == null && snapshot.getStatus() == Snapshot.Status.BackedUp) { + if (snapshot != null && snapshot.getRemoved() == null && snapshot.getState() == Snapshot.State.BackedUp) { return snapshot; } else { return null; diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 641f25ba0b9..54639a87b3e 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -16,125 +16,9 @@ // under the License. package com.cloud.api; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; - -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; - -import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.ResponseGenerator; -import org.apache.log4j.Logger; - -import org.apache.cloudstack.acl.ControlledEntity; -import org.apache.cloudstack.acl.ControlledEntity.ACLType; -import org.apache.cloudstack.api.ApiConstants.HostDetails; -import org.apache.cloudstack.api.ApiConstants.VMDetails; -import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd; -import org.apache.cloudstack.api.response.AccountResponse; - import com.cloud.api.query.ViewResponseHelper; -import com.cloud.api.query.vo.AccountJoinVO; -import com.cloud.api.query.vo.AsyncJobJoinVO; -import com.cloud.api.query.vo.ControlledViewEntity; -import com.cloud.api.query.vo.DataCenterJoinVO; -import com.cloud.api.query.vo.DiskOfferingJoinVO; -import com.cloud.api.query.vo.DomainRouterJoinVO; -import com.cloud.api.query.vo.EventJoinVO; -import com.cloud.api.query.vo.HostJoinVO; -import com.cloud.api.query.vo.InstanceGroupJoinVO; -import com.cloud.api.query.vo.ProjectAccountJoinVO; -import com.cloud.api.query.vo.ProjectInvitationJoinVO; -import com.cloud.api.query.vo.ProjectJoinVO; -import com.cloud.api.query.vo.ResourceTagJoinVO; -import com.cloud.api.query.vo.SecurityGroupJoinVO; -import com.cloud.api.query.vo.ServiceOfferingJoinVO; -import com.cloud.api.query.vo.StoragePoolJoinVO; -import com.cloud.api.query.vo.UserAccountJoinVO; -import com.cloud.api.query.vo.UserVmJoinVO; -import com.cloud.api.query.vo.VolumeJoinVO; +import com.cloud.api.query.vo.*; import com.cloud.api.response.ApiResponseSerializer; -import org.apache.cloudstack.api.response.AsyncJobResponse; -import org.apache.cloudstack.api.response.AutoScalePolicyResponse; -import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse; -import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse; -import org.apache.cloudstack.api.response.CapabilityResponse; -import org.apache.cloudstack.api.response.CapacityResponse; -import org.apache.cloudstack.api.response.ClusterResponse; -import org.apache.cloudstack.api.response.ConditionResponse; -import org.apache.cloudstack.api.response.ConfigurationResponse; -import org.apache.cloudstack.api.response.ControlledEntityResponse; -import org.apache.cloudstack.api.response.CounterResponse; -import org.apache.cloudstack.api.response.CreateCmdResponse; -import org.apache.cloudstack.api.response.DiskOfferingResponse; -import org.apache.cloudstack.api.response.DomainResponse; -import org.apache.cloudstack.api.response.DomainRouterResponse; -import org.apache.cloudstack.api.response.EventResponse; -import org.apache.cloudstack.api.response.ExtractResponse; -import org.apache.cloudstack.api.response.FirewallResponse; -import org.apache.cloudstack.api.response.FirewallRuleResponse; -import org.apache.cloudstack.api.response.GuestOSResponse; -import org.apache.cloudstack.api.response.HostResponse; -import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse; -import org.apache.cloudstack.api.response.ControlledViewEntityResponse; -import org.apache.cloudstack.api.response.IPAddressResponse; -import org.apache.cloudstack.api.response.InstanceGroupResponse; -import org.apache.cloudstack.api.response.IpForwardingRuleResponse; -import org.apache.cloudstack.api.response.LBStickinessPolicyResponse; -import org.apache.cloudstack.api.response.LBStickinessResponse; -import org.apache.cloudstack.api.response.LDAPConfigResponse; -import org.apache.cloudstack.api.response.LoadBalancerResponse; -import org.apache.cloudstack.api.response.NetworkACLResponse; -import org.apache.cloudstack.api.response.NetworkOfferingResponse; -import org.apache.cloudstack.api.response.NetworkResponse; -import org.apache.cloudstack.api.response.PhysicalNetworkResponse; -import org.apache.cloudstack.api.response.PodResponse; -import org.apache.cloudstack.api.response.PrivateGatewayResponse; -import org.apache.cloudstack.api.response.ProjectAccountResponse; -import org.apache.cloudstack.api.response.ProjectInvitationResponse; -import org.apache.cloudstack.api.response.ProjectResponse; -import org.apache.cloudstack.api.response.ProviderResponse; -import org.apache.cloudstack.api.response.RemoteAccessVpnResponse; -import org.apache.cloudstack.api.response.ResourceCountResponse; -import org.apache.cloudstack.api.response.ResourceLimitResponse; -import org.apache.cloudstack.api.response.ResourceTagResponse; -import org.apache.cloudstack.api.response.SecurityGroupResponse; -import org.apache.cloudstack.api.response.SecurityGroupRuleResponse; -import org.apache.cloudstack.api.response.ServiceOfferingResponse; -import org.apache.cloudstack.api.response.ServiceResponse; -import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse; -import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse; -import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse; -import org.apache.cloudstack.api.response.SnapshotPolicyResponse; -import org.apache.cloudstack.api.response.SnapshotResponse; -import org.apache.cloudstack.api.response.SnapshotScheduleResponse; -import org.apache.cloudstack.api.response.StaticRouteResponse; -import org.apache.cloudstack.api.response.StorageNetworkIpRangeResponse; -import org.apache.cloudstack.api.response.StoragePoolResponse; -import org.apache.cloudstack.api.response.SwiftResponse; -import org.apache.cloudstack.api.response.SystemVmInstanceResponse; -import org.apache.cloudstack.api.response.SystemVmResponse; -import org.apache.cloudstack.api.response.TemplatePermissionsResponse; -import org.apache.cloudstack.api.response.TemplateResponse; -import org.apache.cloudstack.api.response.TrafficTypeResponse; -import org.apache.cloudstack.api.response.UserResponse; -import org.apache.cloudstack.api.response.UserVmResponse; -import org.apache.cloudstack.api.response.VirtualRouterProviderResponse; -import org.apache.cloudstack.api.response.VlanIpRangeResponse; -import org.apache.cloudstack.api.response.VolumeResponse; -import org.apache.cloudstack.api.response.VpcOfferingResponse; -import org.apache.cloudstack.api.response.VpcResponse; -import org.apache.cloudstack.api.response.VpnUsersResponse; -import org.apache.cloudstack.api.response.ZoneResponse; - -import org.apache.cloudstack.api.response.S3Response; import com.cloud.async.AsyncJob; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityVO; @@ -143,53 +27,21 @@ import com.cloud.configuration.Configuration; import com.cloud.configuration.Resource.ResourceOwnerType; import com.cloud.configuration.ResourceCount; import com.cloud.configuration.ResourceLimit; -import com.cloud.dc.ClusterVO; -import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.HostPodVO; -import com.cloud.dc.Pod; -import com.cloud.dc.StorageNetworkIpRange; -import com.cloud.dc.Vlan; +import com.cloud.dc.*; import com.cloud.dc.Vlan.VlanType; -import com.cloud.dc.VlanVO; import com.cloud.domain.Domain; import com.cloud.event.Event; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.hypervisor.HypervisorCapabilities; -import com.cloud.network.IPAddressVO; -import com.cloud.network.IpAddress; -import com.cloud.network.Network; +import com.cloud.network.*; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; -import com.cloud.network.NetworkProfile; -import com.cloud.network.NetworkVO; import com.cloud.network.Networks.TrafficType; -import com.cloud.network.PhysicalNetwork; -import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.PhysicalNetworkTrafficType; -import com.cloud.network.PhysicalNetworkVO; -import com.cloud.network.RemoteAccessVpn; -import com.cloud.network.Site2SiteCustomerGateway; -import com.cloud.network.Site2SiteVpnConnection; -import com.cloud.network.Site2SiteVpnGateway; -import com.cloud.network.VirtualRouterProvider; -import com.cloud.network.VpnUser; -import com.cloud.network.as.AutoScalePolicy; -import com.cloud.network.as.AutoScaleVmGroup; -import com.cloud.network.as.AutoScaleVmProfile; -import com.cloud.network.as.AutoScaleVmProfileVO; -import com.cloud.network.as.Condition; -import com.cloud.network.as.ConditionVO; -import com.cloud.network.as.Counter; +import com.cloud.network.as.*; import com.cloud.network.router.VirtualRouter; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.FirewallRuleVO; -import com.cloud.network.rules.LoadBalancer; -import com.cloud.network.rules.PortForwardingRule; -import com.cloud.network.rules.StaticNatRule; -import com.cloud.network.rules.StickinessPolicy; +import com.cloud.network.rules.*; import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityRule; import com.cloud.network.security.SecurityRule.SecurityRuleType; @@ -207,25 +59,11 @@ import com.cloud.projects.ProjectInvitation; import com.cloud.server.Criteria; import com.cloud.server.ResourceTag; import com.cloud.server.ResourceTag.TaggedResourceType; -import com.cloud.storage.GuestOS; -import com.cloud.storage.GuestOSCategoryVO; -import com.cloud.storage.S3; -import com.cloud.storage.Snapshot; +import com.cloud.storage.*; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.StorageStats; -import com.cloud.storage.Swift; -import com.cloud.storage.UploadVO; -import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateS3VO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.VMTemplateSwiftVO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; -import com.cloud.storage.VolumeVO; import com.cloud.storage.snapshot.SnapshotPolicy; import com.cloud.storage.snapshot.SnapshotSchedule; import com.cloud.template.VirtualMachineTemplate; @@ -242,6 +80,21 @@ import com.cloud.vm.InstanceGroup; import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.Type; +import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.acl.ControlledEntity.ACLType; +import org.apache.cloudstack.api.ApiConstants.HostDetails; +import org.apache.cloudstack.api.ApiConstants.VMDetails; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.ResponseGenerator; +import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd; +import org.apache.cloudstack.api.response.*; +import org.apache.log4j.Logger; + +import java.text.DecimalFormat; +import java.util.*; + +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; public class ApiResponseHelper implements ResponseGenerator { @@ -378,7 +231,7 @@ public class ApiResponseHelper implements ResponseGenerator { snapshotResponse.setCreated(snapshot.getCreated()); snapshotResponse.setName(snapshot.getName()); snapshotResponse.setIntervalType(ApiDBUtils.getSnapshotIntervalTypes(snapshot.getId())); - snapshotResponse.setState(snapshot.getStatus()); + snapshotResponse.setState(snapshot.getState()); //set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Snapshot, snapshot.getId()); diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index ed2720082c4..b4612ae6999 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -50,10 +50,10 @@ import javax.crypto.spec.SecretKeySpec; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import com.cloud.event.ActionEventUtils; import com.cloud.utils.ReflectUtil; import org.apache.cloudstack.acl.APILimitChecker; import org.apache.cloudstack.acl.APIChecker; -import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.*; import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd; @@ -116,7 +116,6 @@ import com.cloud.configuration.ConfigurationVO; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; -import com.cloud.event.EventUtils; import com.cloud.exception.AccountLimitException; import com.cloud.exception.CloudAuthenticationException; import com.cloud.exception.InsufficientCapacityException; @@ -467,7 +466,7 @@ public class ApiServer implements HttpRequestHandler { asyncCmd.setStartEventId(startEventId); // save the scheduled event - Long eventId = EventUtils.saveScheduledEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, + Long eventId = ActionEventUtils.onScheduledActionEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(), asyncCmd.getEventDescription(), startEventId); if (startEventId == 0) { diff --git a/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java b/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java index 25298a9eebd..74200e2d138 100755 --- a/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java +++ b/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java @@ -16,20 +16,10 @@ // under the License. package com.cloud.baremetal; -import java.util.Date; -import java.util.List; - -import javax.ejb.Local; - -import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; -import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd; -import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; -import org.apache.log4j.Logger; - import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.DataCenterVO; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; +import com.cloud.event.UsageEventUtils; import com.cloud.exception.ResourceAllocationException; import com.cloud.host.Host; import com.cloud.host.HostVO; @@ -46,6 +36,14 @@ import com.cloud.user.Account; import com.cloud.utils.component.Inject; import com.cloud.utils.db.DB; import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; +import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd; +import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import java.util.Date; +import java.util.List; @Local(value=TemplateAdapter.class) public class BareMetalTemplateAdapter extends TemplateAdapterBase implements TemplateAdapter { @@ -82,9 +80,9 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem private void templateCreateUsage(VMTemplateVO template, HostVO host) { if (template.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, template.getAccountId(), host.getDataCenterId(), - template.getId(), template.getName(), null, template.getSourceTemplateId(), 0L); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_TEMPLATE_CREATE, template.getAccountId(), host.getDataCenterId(), + template.getId(), template.getName(), null, template.getSourceTemplateId(), 0L, + template.getClass().getName(), template.getUuid()); } } @@ -172,8 +170,8 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem _tmpltZoneDao.remove(templateZone.getId()); } - UsageEventVO usageEvent = new UsageEventVO(eventType, account.getId(), pxeServer.getDataCenterId(), templateId, null); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(eventType, account.getId(), pxeServer.getDataCenterId(), + templateId, null, template.getClass().getName(), template.getUuid()); } finally { if (lock != null) { _tmpltHostDao.releaseFromLockTable(lock.getId()); diff --git a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java index 57cfb396d3e..6ff37ea2b22 100755 --- a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java +++ b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java @@ -16,28 +16,11 @@ // under the License. package com.cloud.baremetal; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Executors; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd; -import org.apache.cloudstack.api.command.user.vm.DeployVMCmd; -import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd; -import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; -import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; -import org.apache.log4j.Logger; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.baremetal.IpmISetBootDevCommand; import com.cloud.agent.api.baremetal.IpmiBootorResetCommand; import com.cloud.agent.manager.Commands; -import org.apache.cloudstack.api.command.user.vm.StartVMCmd; import com.cloud.baremetal.PxeServerManager.PxeServerType; import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; @@ -47,14 +30,8 @@ import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; import com.cloud.domain.DomainVO; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.exception.StorageUnavailableException; +import com.cloud.event.UsageEventUtils; +import com.cloud.exception.*; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -71,11 +48,7 @@ import com.cloud.storage.Volume; import com.cloud.template.TemplateAdapter; import com.cloud.template.TemplateAdapter.TemplateAdapterType; import com.cloud.template.TemplateProfile; -import com.cloud.user.Account; -import com.cloud.user.AccountVO; -import com.cloud.user.SSHKeyPair; -import com.cloud.user.User; -import com.cloud.user.UserContext; +import com.cloud.user.*; import com.cloud.uservm.UserVm; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -88,19 +61,26 @@ import com.cloud.utils.db.DB; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.StateListener; import com.cloud.utils.net.NetUtils; -import com.cloud.vm.BareMetalVmService; -import com.cloud.vm.NicProfile; -import com.cloud.vm.NicVO; -import com.cloud.vm.ReservationContext; -import com.cloud.vm.UserVmManagerImpl; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VirtualMachine; +import com.cloud.vm.*; import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachine.Type; -import com.cloud.vm.VirtualMachineName; -import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile.Param; +import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd; +import org.apache.cloudstack.api.command.user.vm.DeployVMCmd; +import org.apache.cloudstack.api.command.user.vm.StartVMCmd; +import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd; +import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; @Local(value={BareMetalVmManager.class, BareMetalVmService.class}) public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMetalVmManager, BareMetalVmService, Manager, @@ -367,8 +347,9 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet s_logger.debug("Successfully allocated DB entry for " + vm); } UserContext.current().setEventDetails("Vm Id: " + vm.getId()); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_CREATE, accountId, cmd.getZoneId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(), HypervisorType.BareMetal.toString()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, cmd.getZoneId(), vm.getId(), + vm.getHostName(), offering.getId(), template.getId(), HypervisorType.BareMetal.toString(), + VirtualMachine.class.getName(), vm.getUuid()); _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm); diff --git a/server/src/com/cloud/configuration/DefaultInterceptorLibrary.java b/server/src/com/cloud/configuration/DefaultInterceptorLibrary.java index ced2618cec6..13a22dbe827 100644 --- a/server/src/com/cloud/configuration/DefaultInterceptorLibrary.java +++ b/server/src/com/cloud/configuration/DefaultInterceptorLibrary.java @@ -16,18 +16,18 @@ // under the License. package com.cloud.configuration; -import java.util.List; - -import com.cloud.event.ActionEventCallback; +import com.cloud.event.ActionEventUtils; import com.cloud.utils.component.AnnotationInterceptor; import com.cloud.utils.component.InterceptorLibrary; import com.cloud.utils.db.DatabaseCallback; +import java.util.List; + public class DefaultInterceptorLibrary implements InterceptorLibrary { @Override public void addInterceptors(List> interceptors) { interceptors.add(new DatabaseCallback()); - interceptors.add(new ActionEventCallback()); + interceptors.add(new ActionEventUtils.ActionEventCallback()); } } diff --git a/server/src/com/cloud/event/ActionEventCallback.java b/server/src/com/cloud/event/ActionEventCallback.java deleted file mode 100644 index f941400de64..00000000000 --- a/server/src/com/cloud/event/ActionEventCallback.java +++ /dev/null @@ -1,135 +0,0 @@ -// 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.event; - -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Method; - -import net.sf.cglib.proxy.Callback; -import net.sf.cglib.proxy.MethodInterceptor; -import net.sf.cglib.proxy.MethodProxy; - -import com.cloud.user.UserContext; -import com.cloud.utils.component.AnnotationInterceptor; - -public class ActionEventCallback implements MethodInterceptor, AnnotationInterceptor { - - @Override - public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { - EventVO event = interceptStart(method); - boolean success = true; - try { - return methodProxy.invokeSuper(object, args); - } catch (Exception e){ - success = false; - interceptException(method, event); - throw e; - } finally { - if(success){ - interceptComplete(method, event); - } - } - } - - @Override - public boolean needToIntercept(AnnotatedElement element) { - if (!(element instanceof Method)) { - return false; - - } - Method method = (Method)element; - ActionEvent actionEvent = method.getAnnotation(ActionEvent.class); - if (actionEvent != null) { - return true; - } - - return false; - } - - @Override - public EventVO interceptStart(AnnotatedElement element) { - EventVO event = null; - Method method = (Method)element; - ActionEvent actionEvent = method.getAnnotation(ActionEvent.class); - if (actionEvent != null) { - boolean async = actionEvent.async(); - if(async){ - UserContext ctx = UserContext.current(); - long userId = ctx.getCallerUserId(); - long accountId = ctx.getAccountId(); - long startEventId = ctx.getStartEventId(); - String eventDescription = actionEvent.eventDescription(); - if(ctx.getEventDetails() != null){ - eventDescription += ". "+ctx.getEventDetails(); - } - EventUtils.saveStartedEvent(userId, accountId, actionEvent.eventType(), eventDescription, startEventId); - } - } - return event; - } - - @Override - public void interceptComplete(AnnotatedElement element, EventVO event) { - Method method = (Method)element; - ActionEvent actionEvent = method.getAnnotation(ActionEvent.class); - if (actionEvent != null) { - UserContext ctx = UserContext.current(); - long userId = ctx.getCallerUserId(); - long accountId = ctx.getAccountId(); - long startEventId = ctx.getStartEventId(); - String eventDescription = actionEvent.eventDescription(); - if(ctx.getEventDetails() != null){ - eventDescription += ". "+ctx.getEventDetails(); - } - if(actionEvent.create()){ - //This start event has to be used for subsequent events of this action - startEventId = EventUtils.saveCreatedEvent(userId, accountId, EventVO.LEVEL_INFO, actionEvent.eventType(), "Successfully created entity for "+eventDescription); - ctx.setStartEventId(startEventId); - } else { - EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_INFO, actionEvent.eventType(), "Successfully completed "+eventDescription, startEventId); - } - } - } - - @Override - public void interceptException(AnnotatedElement element, EventVO event) { - Method method = (Method)element; - ActionEvent actionEvent = method.getAnnotation(ActionEvent.class); - if (actionEvent != null) { - UserContext ctx = UserContext.current(); - long userId = ctx.getCallerUserId(); - long accountId = ctx.getAccountId(); - long startEventId = ctx.getStartEventId(); - String eventDescription = actionEvent.eventDescription(); - if(ctx.getEventDetails() != null){ - eventDescription += ". "+ctx.getEventDetails(); - } - if(actionEvent.create()){ - long eventId = EventUtils.saveCreatedEvent(userId, accountId, EventVO.LEVEL_ERROR, actionEvent.eventType(), "Error while creating entity for "+eventDescription); - ctx.setStartEventId(eventId); - } else { - EventUtils.saveEvent(userId, accountId, EventVO.LEVEL_ERROR, actionEvent.eventType(), "Error while "+eventDescription, startEventId); - } - } - } - - @Override - public Callback getCallback() { - return this; - } - -} diff --git a/server/src/com/cloud/event/ActionEventUtils.java b/server/src/com/cloud/event/ActionEventUtils.java new file mode 100755 index 00000000000..744f46f3bc2 --- /dev/null +++ b/server/src/com/cloud/event/ActionEventUtils.java @@ -0,0 +1,288 @@ +// 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.event; + +import com.cloud.event.dao.EventDao; +import com.cloud.server.ManagementServer; +import com.cloud.user.Account; +import com.cloud.user.AccountVO; +import com.cloud.user.User; +import com.cloud.user.UserContext; +import com.cloud.user.dao.AccountDao; +import com.cloud.user.dao.UserDao; +import com.cloud.utils.component.Adapters; +import com.cloud.utils.component.AnnotationInterceptor; +import com.cloud.utils.component.ComponentLocator; +import net.sf.cglib.proxy.Callback; +import net.sf.cglib.proxy.MethodInterceptor; +import net.sf.cglib.proxy.MethodProxy; +import org.apache.cloudstack.framework.events.EventBus; +import org.apache.cloudstack.framework.events.EventBusException; +import org.apache.log4j.Logger; + +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Method; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +public class ActionEventUtils { + + private static EventDao _eventDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(EventDao.class); + private static AccountDao _accountDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(AccountDao.class); + protected static UserDao _userDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(UserDao.class); + private static final Logger s_logger = Logger.getLogger(ActionEventUtils.class); + + // get the event bus provider if configured + protected static EventBus _eventBus = null; + + static { + Adapters eventBusImpls = ComponentLocator.getLocator(ManagementServer.Name).getAdapters(EventBus.class); + if (eventBusImpls != null) { + Enumeration eventBusenum = eventBusImpls.enumeration(); + if (eventBusenum != null && eventBusenum.hasMoreElements()) { + _eventBus = eventBusenum.nextElement(); // configure event bus if configured + } + } + } + + public static Long onActionEvent(Long userId, Long accountId, Long domainId, String type, String description) { + + publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), + type, com.cloud.event.Event.State.Completed); + + Event event = persistActionEvent(userId, accountId, domainId, null, type, Event.State.Completed, + description, null); + + return event.getId(); + } + + /* + * Save event after scheduling an async job + */ + public static Long onScheduledActionEvent(Long userId, Long accountId, String type, String description, + long startEventId) { + + publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, + com.cloud.event.Event.State.Scheduled); + + Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Scheduled, + description, startEventId); + + return event.getId(); + } + + /* + * Save event after starting execution of an async job + */ + public static Long onStartedActionEvent(Long userId, Long accountId, String type, String description, + long startEventId) { + + publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, + com.cloud.event.Event.State.Started); + + Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Started, + description, startEventId); + return event.getId(); + } + + public static Long onCompletedActionEvent(Long userId, Long accountId, String level, String type, + String description, long startEventId) { + + publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, + com.cloud.event.Event.State.Completed); + + Event event = persistActionEvent(userId, accountId, null, level, type, Event.State.Completed, + description, startEventId); + + return event.getId(); + } + + public static Long onCreatedActionEvent(Long userId, Long accountId, String level, String type, String description) { + + publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, + com.cloud.event.Event.State.Created); + + Event event = persistActionEvent(userId, accountId, null, level, type, Event.State.Created, description, null); + + return event.getId(); + } + + private static Event persistActionEvent(Long userId, Long accountId, Long domainId, String level, String type, + Event.State state, String description, Long startEventId) { + EventVO event = new EventVO(); + event.setUserId(userId); + event.setAccountId(accountId); + event.setType(type); + event.setState(state); + event.setDescription(description); + if (domainId != null) { + event.setDomainId(domainId); + } else { + event.setDomainId(getDomainId(accountId)); + } + if (level != null && !level.isEmpty()) { + event.setLevel(level); + } + if (startEventId != null) { + event.setStartId(startEventId); + } + event = _eventDao.persist(event); + return event; + } + + private static void publishOnEventBus(long userId, long accountId, String eventCategory, + String eventType, Event.State state) { + if (_eventBus == null) { + return; // no provider is configured to provide events bus, so just return + } + + org.apache.cloudstack.framework.events.Event event = new org.apache.cloudstack.framework.events.Event( + ManagementServer.Name, + eventCategory, + eventType, + EventTypes.getEntityForEvent(eventType), null); + + Map eventDescription = new HashMap(); + Account account = _accountDao.findById(accountId); + User user = _userDao.findById(userId); + eventDescription.put("user", user.getUuid()); + eventDescription.put("account", account.getUuid()); + eventDescription.put("event", eventType); + eventDescription.put("status", state.toString()); + event.setDescription(eventDescription); + + try { + _eventBus.publish(event); + } catch (EventBusException e) { + s_logger.warn("Failed to publish action event on the the event bus."); + } + } + + private static long getDomainId(long accountId){ + AccountVO account = _accountDao.findByIdIncludingRemoved(accountId); + return account.getDomainId(); + } + + public static class ActionEventCallback implements MethodInterceptor, AnnotationInterceptor { + + @Override + public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { + EventVO event = interceptStart(method); + boolean success = true; + try { + return methodProxy.invokeSuper(object, args); + } catch (Exception e){ + success = false; + interceptException(method, event); + throw e; + } finally { + if(success){ + interceptComplete(method, event); + } + } + } + + @Override + public boolean needToIntercept(AnnotatedElement element) { + if (!(element instanceof Method)) { + return false; + + } + Method method = (Method)element; + ActionEvent actionEvent = method.getAnnotation(ActionEvent.class); + if (actionEvent != null) { + return true; + } + + return false; + } + + @Override + public EventVO interceptStart(AnnotatedElement element) { + EventVO event = null; + Method method = (Method)element; + ActionEvent actionEvent = method.getAnnotation(ActionEvent.class); + if (actionEvent != null) { + boolean async = actionEvent.async(); + if(async){ + UserContext ctx = UserContext.current(); + long userId = ctx.getCallerUserId(); + long accountId = ctx.getAccountId(); + long startEventId = ctx.getStartEventId(); + String eventDescription = actionEvent.eventDescription(); + if(ctx.getEventDetails() != null){ + eventDescription += ". "+ctx.getEventDetails(); + } + ActionEventUtils.onStartedActionEvent(userId, accountId, actionEvent.eventType(), eventDescription, startEventId); + } + } + return event; + } + + @Override + public void interceptComplete(AnnotatedElement element, EventVO event) { + Method method = (Method)element; + ActionEvent actionEvent = method.getAnnotation(ActionEvent.class); + if (actionEvent != null) { + UserContext ctx = UserContext.current(); + long userId = ctx.getCallerUserId(); + long accountId = ctx.getAccountId(); + long startEventId = ctx.getStartEventId(); + String eventDescription = actionEvent.eventDescription(); + if(ctx.getEventDetails() != null){ + eventDescription += ". "+ctx.getEventDetails(); + } + if(actionEvent.create()){ + //This start event has to be used for subsequent events of this action + startEventId = ActionEventUtils.onCreatedActionEvent(userId, accountId, EventVO.LEVEL_INFO, actionEvent.eventType(), "Successfully created entity for " + eventDescription); + ctx.setStartEventId(startEventId); + } else { + ActionEventUtils.onCompletedActionEvent(userId, accountId, EventVO.LEVEL_INFO, actionEvent.eventType(), "Successfully completed " + eventDescription, startEventId); + } + } + } + + @Override + public void interceptException(AnnotatedElement element, EventVO event) { + Method method = (Method)element; + ActionEvent actionEvent = method.getAnnotation(ActionEvent.class); + if (actionEvent != null) { + UserContext ctx = UserContext.current(); + long userId = ctx.getCallerUserId(); + long accountId = ctx.getAccountId(); + long startEventId = ctx.getStartEventId(); + String eventDescription = actionEvent.eventDescription(); + if(ctx.getEventDetails() != null){ + eventDescription += ". "+ctx.getEventDetails(); + } + if(actionEvent.create()){ + long eventId = ActionEventUtils.onCreatedActionEvent(userId, accountId, EventVO.LEVEL_ERROR, actionEvent.eventType(), "Error while creating entity for " + eventDescription); + ctx.setStartEventId(eventId); + } else { + ActionEventUtils.onCompletedActionEvent(userId, accountId, EventVO.LEVEL_ERROR, actionEvent.eventType(), "Error while " + eventDescription, startEventId); + } + } + } + + @Override + public Callback getCallback() { + return this; + } + } +} diff --git a/server/src/com/cloud/event/AlertGenerator.java b/server/src/com/cloud/event/AlertGenerator.java new file mode 100644 index 00000000000..42863778cfd --- /dev/null +++ b/server/src/com/cloud/event/AlertGenerator.java @@ -0,0 +1,87 @@ +// 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.event; + +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.server.ManagementServer; +import com.cloud.utils.component.Adapters; +import com.cloud.utils.component.ComponentLocator; +import org.apache.cloudstack.framework.events.*; +import org.apache.log4j.Logger; + +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +public class AlertGenerator { + + private static final Logger s_logger = Logger.getLogger(AlertGenerator.class); + private static DataCenterDao _dcDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(DataCenterDao.class); + private static HostPodDao _podDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(HostPodDao.class); + + // get the event bus provider if configured + protected static EventBus _eventBus = null; + static { + Adapters eventBusImpls = ComponentLocator.getLocator(ManagementServer.Name).getAdapters(EventBus.class); + if (eventBusImpls != null) { + Enumeration eventBusenum = eventBusImpls.enumeration(); + if (eventBusenum != null && eventBusenum.hasMoreElements()) { + _eventBus = eventBusenum.nextElement(); // configure event bus if configured + } + } + } + + public static void publishAlertOnEventBus(String alertType, long dataCenterId, Long podId, String subject, String body) { + if (_eventBus == null) { + return; // no provider is configured to provider events bus, so just return + } + + org.apache.cloudstack.framework.events.Event event = + new org.apache.cloudstack.framework.events.Event(ManagementServer.Name, + EventCategory.ALERT_EVENT.getName(), + alertType, + null, + null); + + Map eventDescription = new HashMap(); + DataCenterVO dc = _dcDao.findById(dataCenterId); + HostPodVO pod = _podDao.findById(podId); + + eventDescription.put("event", alertType); + if (dc != null) { + eventDescription.put("dataCenterId", dc.getUuid()); + } else { + eventDescription.put("dataCenterId", null); + } + if (pod != null) { + eventDescription.put("podId", pod.getUuid()); + } else { + eventDescription.put("podId", null); + } + event.setDescription(eventDescription); + + try { + _eventBus.publish(event); + } catch (EventBusException e) { + s_logger.warn("Failed to publish alert on the the event bus."); + } + } +} diff --git a/server/src/com/cloud/event/EventUtils.java b/server/src/com/cloud/event/EventUtils.java deleted file mode 100755 index 3672ee72d4e..00000000000 --- a/server/src/com/cloud/event/EventUtils.java +++ /dev/null @@ -1,102 +0,0 @@ -// 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.event; - -import com.cloud.event.dao.EventDao; -import com.cloud.server.ManagementServer; -import com.cloud.user.AccountVO; -import com.cloud.user.dao.AccountDao; -import com.cloud.utils.component.ComponentLocator; - -public class EventUtils { - private static EventDao _eventDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(EventDao.class); - private static AccountDao _accountDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(AccountDao.class); - - public static Long saveEvent(Long userId, Long accountId, Long domainId, String type, String description) { - EventVO event = new EventVO(); - event.setUserId(userId); - event.setAccountId(accountId); - event.setDomainId(domainId); - event.setType(type); - event.setDescription(description); - event = _eventDao.persist(event); - return event.getId(); - } - - /* - * Save event after scheduling an async job - */ - public static Long saveScheduledEvent(Long userId, Long accountId, String type, String description, long startEventId) { - EventVO event = new EventVO(); - event.setUserId(userId); - event.setAccountId(accountId); - event.setDomainId(getDomainId(accountId)); - event.setType(type); - event.setStartId(startEventId); - event.setState(Event.State.Scheduled); - event.setDescription("Scheduled async job for "+description); - event = _eventDao.persist(event); - return event.getId(); - } - - /* - * Save event after starting execution of an async job - */ - public static Long saveStartedEvent(Long userId, Long accountId, String type, String description, long startEventId) { - EventVO event = new EventVO(); - event.setUserId(userId); - event.setAccountId(accountId); - event.setDomainId(getDomainId(accountId)); - event.setType(type); - event.setState(Event.State.Started); - event.setDescription("Starting job for "+description); - event.setStartId(startEventId); - event = _eventDao.persist(event); - return event.getId(); - } - - public static Long saveEvent(Long userId, Long accountId, String level, String type, String description, long startEventId) { - EventVO event = new EventVO(); - event.setUserId(userId); - event.setAccountId(accountId); - event.setDomainId(getDomainId(accountId)); - event.setType(type); - event.setDescription(description); - event.setLevel(level); - event.setStartId(startEventId); - event = _eventDao.persist(event); - return (event != null ? event.getId() : null); - } - - public static Long saveCreatedEvent(Long userId, Long accountId, String level, String type, String description) { - EventVO event = new EventVO(); - event.setUserId(userId); - event.setAccountId(accountId); - event.setDomainId(getDomainId(accountId)); - event.setType(type); - event.setLevel(level); - event.setState(Event.State.Created); - event.setDescription(description); - event = _eventDao.persist(event); - return event.getId(); - } - - private static long getDomainId(long accountId){ - AccountVO account = _accountDao.findByIdIncludingRemoved(accountId); - return account.getDomainId(); - } -} diff --git a/server/src/com/cloud/event/UsageEventUtils.java b/server/src/com/cloud/event/UsageEventUtils.java new file mode 100644 index 00000000000..904525ea2f0 --- /dev/null +++ b/server/src/com/cloud/event/UsageEventUtils.java @@ -0,0 +1,119 @@ +package com.cloud.event; + +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.event.dao.UsageEventDao; +import com.cloud.server.ManagementServer; +import com.cloud.user.Account; +import com.cloud.user.dao.AccountDao; +import com.cloud.utils.component.Adapters; +import com.cloud.utils.component.ComponentLocator; +import org.apache.cloudstack.framework.events.EventBus; +import org.apache.cloudstack.framework.events.Event; +import org.apache.cloudstack.framework.events.EventBusException; +import org.apache.log4j.Logger; + +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +public class UsageEventUtils { + + private static UsageEventDao _usageEventDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(UsageEventDao.class); + private static AccountDao _accountDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(AccountDao.class); + private static DataCenterDao _dcDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(DataCenterDao.class); + private static final Logger s_logger = Logger.getLogger(UsageEventUtils.class); + + // get the event bus provider if configured + protected static EventBus _eventBus = null; + static { + Adapters eventBusImpls = ComponentLocator.getLocator(ManagementServer.Name).getAdapters(EventBus.class); + if (eventBusImpls != null) { + Enumeration eventBusenum = eventBusImpls.enumeration(); + if (eventBusenum != null && eventBusenum.hasMoreElements()) { + _eventBus = eventBusenum.nextElement(); // configure event bus if configured + } + } + } + + public static void publishUsageEvent(String usageType, long accountId, long zoneId, + long resourceId, String resourceName, + Long offeringId, Long templateId, Long size, + String entityType, String entityUUID) { + saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size); + publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID); + } + + public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, + String resourceName, String entityType, String entityUUID) { + saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName); + publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID); + } + + public static void publishUsageEvent(String usageType, long accountId, long zoneId, + long ipAddressId, String ipAddress, boolean isSourceNat, + String guestType, boolean isSystem, String entityType, String entityUUID) { + saveUsageEvent(usageType, accountId, zoneId, ipAddressId, ipAddress, isSourceNat, guestType, isSystem); + publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID); + } + + public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, + String resourceName, Long offeringId, Long templateId, String resourceType, + String entityType, String entityUUID) { + saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, resourceType); + publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID); + } + + public static void publishUsageEvent(String usageType, long accountId,long zoneId, long vmId, + long securityGroupId, String entityType, String entityUUID) { + saveUsageEvent(usageType, accountId, zoneId, vmId, securityGroupId); + publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID); + } + + public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, Long size) { + _usageEventDao.persist( new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size)); + } + + public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName) { + _usageEventDao.persist( new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName)); + } + + public static void saveUsageEvent(String usageType, long accountId, long zoneId, long ipAddressId, String ipAddress, boolean isSourceNat, String guestType, boolean isSystem) { + _usageEventDao.persist( new UsageEventVO(usageType, accountId, zoneId, ipAddressId, ipAddress, isSourceNat, guestType, isSystem)); + } + + public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, String resourceType) { + _usageEventDao.persist( new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, resourceType)); + } + + public static void saveUsageEvent(String usageType, long accountId,long zoneId, long vmId, long securityGroupId) { + _usageEventDao.persist( new UsageEventVO( usageType, accountId, zoneId, vmId, securityGroupId)); + } + + private static void publishUsageEvent(String usageEventType, Long accountId, Long zoneId, String resourceType, String resourceUUID) { + + if (_eventBus == null) { + return; // no provider is configured to provider events bus, so just return + } + + Account account = _accountDao.findById(accountId); + DataCenterVO dc = _dcDao.findById(zoneId); + + Event event = new Event(ManagementServer.Name, EventCategory.USAGE_EVENT.getName(), usageEventType, + resourceType, resourceUUID); + + Map eventDescription = new HashMap(); + eventDescription.put("account", account.getUuid()); + eventDescription.put("zone", dc.getUuid()); + eventDescription.put("event", usageEventType); + eventDescription.put("resource", resourceType); + eventDescription.put("id", resourceUUID); + event.setDescription(eventDescription); + + try { + _eventBus.publish(event); + } catch (EventBusException e) { + s_logger.warn("Failed to publish usage event on the the event bus."); + } + } +} diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 0a4851f3005..3d83487e89b 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -16,39 +16,9 @@ // under the License. package com.cloud.network; -import java.net.URI; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.acl.ControlledEntity.ACLType; -import org.apache.cloudstack.acl.SecurityChecker.AccessType; -import org.apache.log4j.Logger; - import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; -import com.cloud.agent.api.AgentControlAnswer; -import com.cloud.agent.api.AgentControlCommand; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.CheckNetworkAnswer; -import com.cloud.agent.api.CheckNetworkCommand; -import com.cloud.agent.api.Command; -import com.cloud.agent.api.StartupCommand; -import com.cloud.agent.api.StartupRoutingCommand; +import com.cloud.agent.api.*; import com.cloud.agent.api.to.NicTO; import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; @@ -56,15 +26,9 @@ import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.AccountVlanMapVO; -import com.cloud.dc.DataCenter; +import com.cloud.dc.*; import com.cloud.dc.DataCenter.NetworkType; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.Pod; -import com.cloud.dc.PodVlanMapVO; -import com.cloud.dc.Vlan; import com.cloud.dc.Vlan.VlanType; -import com.cloud.dc.VlanVO; import com.cloud.dc.dao.AccountVlanMapDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.PodVlanMapDao; @@ -75,63 +39,30 @@ import com.cloud.deploy.DeploymentPlan; import com.cloud.domain.Domain; import com.cloud.domain.dao.DomainDao; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; +import com.cloud.event.UsageEventUtils; import com.cloud.event.dao.UsageEventDao; -import com.cloud.exception.AccountLimitException; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.ConnectionException; -import com.cloud.exception.InsufficientAddressCapacityException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InsufficientVirtualNetworkCapcityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.exception.UnsupportedServiceException; +import com.cloud.exception.*; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.IpAddress.State; -import com.cloud.network.Network.Capability; -import com.cloud.network.Network.GuestType; -import com.cloud.network.Network.Provider; -import com.cloud.network.Network.Service; +import com.cloud.network.Network.*; import com.cloud.network.Networks.AddressFormat; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.LoadBalancerDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.NetworkServiceMapDao; -import com.cloud.network.dao.PhysicalNetworkDao; -import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; -import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao; -import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO; -import com.cloud.network.element.DhcpServiceProvider; -import com.cloud.network.element.IpDeployer; -import com.cloud.network.element.LoadBalancingServiceProvider; -import com.cloud.network.element.NetworkElement; -import com.cloud.network.element.StaticNatServiceProvider; -import com.cloud.network.element.UserDataServiceProvider; +import com.cloud.network.dao.*; +import com.cloud.network.element.*; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; import com.cloud.network.lb.LoadBalancingRulesManager; -import com.cloud.network.rules.FirewallManager; -import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.*; import com.cloud.network.rules.FirewallRule.Purpose; -import com.cloud.network.rules.FirewallRuleVO; -import com.cloud.network.rules.PortForwardingRuleVO; -import com.cloud.network.rules.RulesManager; -import com.cloud.network.rules.StaticNat; -import com.cloud.network.rules.StaticNatRule; -import com.cloud.network.rules.StaticNatRuleImpl; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.vpc.NetworkACLManager; import com.cloud.network.vpc.VpcManager; @@ -144,11 +75,7 @@ import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; import com.cloud.org.Grouping; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.User; -import com.cloud.user.UserContext; +import com.cloud.user.*; import com.cloud.user.dao.AccountDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -156,30 +83,30 @@ import com.cloud.utils.component.Adapters; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.concurrency.NamedThreadFactory; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; +import com.cloud.utils.db.*; import com.cloud.utils.db.JoinBuilder.JoinType; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.fsm.NoTransitionException; +import com.cloud.utils.fsm.StateMachine2; import com.cloud.utils.net.Ip; import com.cloud.utils.net.NetUtils; -import com.cloud.vm.Nic; -import com.cloud.vm.NicProfile; -import com.cloud.vm.NicVO; -import com.cloud.vm.ReservationContext; -import com.cloud.vm.ReservationContextImpl; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; +import com.cloud.vm.*; import com.cloud.vm.VirtualMachine.Type; -import com.cloud.vm.VirtualMachineProfile; -import com.cloud.vm.VirtualMachineProfileImpl; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; +import org.apache.cloudstack.acl.ControlledEntity.ACLType; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.net.URI; +import java.util.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; /** * NetworkManagerImpl implements NetworkManager. @@ -222,8 +149,6 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { @Inject LoadBalancingRulesManager _lbMgr; @Inject - UsageEventDao _usageEventDao; - @Inject RemoteAccessVpnService _vpnMgr; @Inject PodVlanMapDao _podVlanMapDao; @@ -272,8 +197,14 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { @Inject NetworkACLManager _networkACLMgr; @Inject + UsageEventDao _usageEventDao; + @Inject NetworkModel _networkModel; + protected StateMachine2 _stateMachine; + private final HashMap _systemNetworks = new HashMap(5); + private static Long _privateOfferingId = null; + ScheduledExecutorService _executor; SearchBuilder AssignIpAddressSearch; @@ -405,11 +336,9 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { VlanVO vlan = _vlanDao.findById(addr.getVlanId()); String guestType = vlan.getVlanType().toString(); - - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), addr.getDataCenterId(), addr.getId(), addr.getAddress().toString(), addr.isSourceNat(), guestType, - addr.getSystem()); - _usageEventDao.persist(usageEvent); + addr.getSystem(), addr.getClass().getName(), addr.getUuid()); // don't increment resource count for direct ip addresses if (addr.getAssociatedWithNetworkId() != null) { _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip); @@ -1046,6 +975,8 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { _agentMgr.registerForHostEvents(this, true, false, true); + Network.State.getStateMachine().registerListener(new NetworkStateListener(_usageEventDao, _networksDao)); + s_logger.info("Network Manager is configured."); return true; @@ -1069,6 +1000,7 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { } protected NetworkManagerImpl() { + setStateMachine(); } @Override @@ -1425,9 +1357,7 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { NetworkOfferingVO offering = _networkOfferingDao.findById(network.getNetworkOfferingId()); network.setReservationId(context.getReservationId()); - network.setState(Network.State.Implementing); - - _networksDao.update(networkId, network); + stateTransitTo(network, Event.ImplementNetwork); Network result = guru.implement(network, offering, dest, context); network.setCidr(result.getCidr()); @@ -1440,16 +1370,23 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { // implement network elements and re-apply all the network rules implementNetworkElementsAndResources(dest, context, network, offering); - network.setState(Network.State.Implemented); + stateTransitTo(network,Event.OperationSucceeded); + network.setRestartRequired(false); _networksDao.update(network.getId(), network); implemented.set(guru, network); return implemented; + } catch (NoTransitionException e) { + s_logger.error(e.getMessage()); + return null; } finally { if (implemented.first() == null) { s_logger.debug("Cleaning up because we're unable to implement the network " + network); - network.setState(Network.State.Shutdown); - _networksDao.update(networkId, network); + try { + stateTransitTo(network,Event.OperationFailed); + } catch (NoTransitionException e) { + s_logger.error(e.getMessage()); + } shutdownNetwork(networkId, context, false); } @@ -2045,9 +1982,12 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { s_logger.debug("Network is not implemented: " + network); return false; } - - network.setState(Network.State.Shutdown); - _networksDao.update(network.getId(), network); + try { + stateTransitTo(network, Event.DestroyNetwork); + } catch (NoTransitionException e) { + network.setState(Network.State.Shutdown); + _networksDao.update(network.getId(), network); + } boolean success = shutdownNetworkElementsAndResources(context, cleanupElements, network); @@ -2062,15 +2002,22 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { guru.shutdown(profile, _networkOfferingDao.findById(network.getNetworkOfferingId())); applyProfileToNetwork(network, profile); - - network.setState(Network.State.Allocated); - network.setRestartRequired(false); + try { + stateTransitTo(network, Event.OperationSucceeded); + } catch (NoTransitionException e) { + network.setState(Network.State.Allocated); + network.setRestartRequired(false); + } _networksDao.update(network.getId(), network); _networksDao.clearCheckForGc(networkId); result = true; } else { - network.setState(Network.State.Implemented); - _networksDao.update(network.getId(), network); + try { + stateTransitTo(network, Event.OperationFailed); + } catch (NoTransitionException e) { + network.setState(Network.State.Implemented); + _networksDao.update(network.getId(), network); + } result = false; } txn.commit(); @@ -2230,8 +2177,11 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { s_logger.warn("Failed to delete network " + network + "; was unable to cleanup corresponding ip ranges"); } else { // commit transaction only when ips and vlans for the network are released successfully - network.setState(Network.State.Destroy); - _networksDao.update(network.getId(), network); + try { + stateTransitTo(network, Event.DestroyNetwork); + } catch (NoTransitionException e) { + s_logger.debug(e.getMessage()); + } _networksDao.remove(network.getId()); NetworkOffering ntwkOff = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); @@ -2737,10 +2687,9 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { String guestType = vlan.getVlanType().toString(); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_RELEASE, + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_RELEASE, ip.getAllocatedToAccountId(), ip.getDataCenterId(), addrId, ip.getAddress().addr(), - ip.isSourceNat(), guestType, ip.getSystem()); - _usageEventDao.persist(usageEvent); + ip.isSourceNat(), guestType, ip.getSystem(), ip.getClass().getName(), ip.getUuid()); } ip = _ipAddressDao.markAsUnavailable(addrId); @@ -3458,6 +3407,15 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { return _networkLockTimeout; } + + protected boolean stateTransitTo(NetworkVO network, Network.Event e) throws NoTransitionException { + return _stateMachine.transitTo(network, e, null, _networksDao); + } + + private void setStateMachine() { + _stateMachine = Network.State.getStateMachine(); + } + private Map> getServiceProvidersMap(long networkId) { Map> map = new HashMap>(); List nsms = _ntwkSrvcDao.getServicesInNetwork(networkId); @@ -3471,7 +3429,7 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { } return map; } - + @Override public List getProvidersForServiceInNetwork(Network network, Service service) { Map> service2ProviderMap = getServiceProvidersMap(network.getId()); diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 7530e943116..bcd3f350166 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -16,31 +16,6 @@ // under the License. package com.cloud.network; -import java.security.InvalidParameterException; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - -import org.apache.cloudstack.acl.ControlledEntity.ACLType; -import org.apache.cloudstack.acl.SecurityChecker.AccessType; -import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd; -import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; -import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; -import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; - import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; @@ -58,17 +33,10 @@ import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; +import com.cloud.event.UsageEventUtils; import com.cloud.event.dao.EventDao; import com.cloud.event.dao.UsageEventDao; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientAddressCapacityException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.exception.UnsupportedServiceException; +import com.cloud.exception.*; import com.cloud.network.IpAddress.State; import com.cloud.network.Network.Capability; import com.cloud.network.Network.GuestType; @@ -79,16 +47,7 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetwork.BroadcastDomainRange; import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; import com.cloud.network.addr.PublicIp; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.NetworkDomainDao; -import com.cloud.network.dao.NetworkServiceMapDao; -import com.cloud.network.dao.PhysicalNetworkDao; -import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; -import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; -import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao; -import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO; +import com.cloud.network.dao.*; import com.cloud.network.element.NetworkElement; import com.cloud.network.element.VirtualRouterElement; import com.cloud.network.element.VpcVirtualRouterElement; @@ -109,13 +68,7 @@ import com.cloud.projects.ProjectManager; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.AccountVO; -import com.cloud.user.DomainManager; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.User; -import com.cloud.user.UserContext; +import com.cloud.user.*; import com.cloud.user.dao.AccountDao; import com.cloud.utils.AnnotationHelper; import com.cloud.utils.NumbersUtil; @@ -123,25 +76,28 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.Adapters; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.*; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; -import com.cloud.vm.NicVO; -import com.cloud.vm.ReservationContext; -import com.cloud.vm.ReservationContextImpl; -import com.cloud.vm.SecondaryStorageVmVO; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; +import com.cloud.vm.*; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; +import org.apache.cloudstack.acl.ControlledEntity.ACLType; +import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd; +import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; +import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; +import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.security.InvalidParameterException; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; /** * NetworkServiceImpl implements NetworkService. @@ -1623,10 +1579,8 @@ public class NetworkServiceImpl implements NetworkService, Manager { continue; } long isDefault = (nic.isDefaultNic()) ? 1 : 0; - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), null, oldNetworkOfferingId, null, 0L); - _usageEventDao.persist(usageEvent); - usageEvent = new UsageEventVO(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName(), networkOfferingId, null, isDefault); - _usageEventDao.persist(usageEvent); + UsageEventUtils.saveUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), null, oldNetworkOfferingId, null, 0L); + UsageEventUtils.saveUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName(), networkOfferingId, null, isDefault); } txn.commit(); } else { diff --git a/server/src/com/cloud/network/NetworkStateListener.java b/server/src/com/cloud/network/NetworkStateListener.java new file mode 100644 index 00000000000..130063348eb --- /dev/null +++ b/server/src/com/cloud/network/NetworkStateListener.java @@ -0,0 +1,90 @@ +package com.cloud.network; + +import com.cloud.event.EventCategory; +import com.cloud.event.dao.UsageEventDao; +import com.cloud.network.Network.Event; +import com.cloud.network.Network.State; +import com.cloud.network.dao.NetworkDao; +import com.cloud.server.ManagementServer; +import com.cloud.utils.component.Adapters; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.fsm.StateListener; +import org.apache.cloudstack.framework.events.EventBus; +import org.apache.cloudstack.framework.events.EventBusException; +import org.apache.log4j.Logger; + +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +public class NetworkStateListener implements StateListener { + + protected UsageEventDao _usageEventDao; + protected NetworkDao _networkDao; + + // get the event bus provider if configured + protected static EventBus _eventBus = null; + static { + Adapters eventBusImpls = ComponentLocator.getLocator(ManagementServer.Name).getAdapters(EventBus.class); + if (eventBusImpls != null) { + Enumeration eventBusenum = eventBusImpls.enumeration(); + if (eventBusenum != null && eventBusenum.hasMoreElements()) { + _eventBus = eventBusenum.nextElement(); // configure event bus if configured + } + } + } + + private static final Logger s_logger = Logger.getLogger(NetworkStateListener.class); + + public NetworkStateListener(UsageEventDao usageEventDao, NetworkDao networkDao) { + this._usageEventDao = usageEventDao; + this._networkDao = networkDao; + } + + @Override + public boolean preStateTransitionEvent(State oldState, Event event, State newState, Network vo, boolean status, Object opaque) { + pubishOnEventBus(event.name(), "preStateTransitionEvent", vo, oldState, newState); + return true; + } + + @Override + public boolean postStateTransitionEvent(State oldState, Event event, State newState, Network vo, boolean status, Object opaque) { + pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState); + return true; + } + + private void pubishOnEventBus(String event, String status, Network vo, State oldState, State newState) { + + if (_eventBus == null) { + return; // no provider is configured to provide events bus, so just return + } + + String resourceName = getEntityFromClassName(Network.class.getName()); + org.apache.cloudstack.framework.events.Event eventMsg = new org.apache.cloudstack.framework.events.Event( + ManagementServer.Name, + EventCategory.RESOURCE_STATE_CHANGE_EVENT.getName(), + event, + resourceName, + vo.getUuid()); + Map eventDescription = new HashMap(); + eventDescription.put("resource", resourceName); + eventDescription.put("id", vo.getUuid()); + eventDescription.put("old-state", oldState.name()); + eventDescription.put("new-state", newState.name()); + eventMsg.setDescription(eventDescription); + try { + _eventBus.publish(eventMsg); + } catch (EventBusException e) { + s_logger.warn("Failed to publish state change event on the the event bus."); + } + } + + private String getEntityFromClassName(String entityClassName) { + int index = entityClassName.lastIndexOf("."); + String entityName = entityClassName; + if (index != -1) { + entityName = entityClassName.substring(index+1); + } + return entityName; + } +} diff --git a/server/src/com/cloud/network/NetworkVO.java b/server/src/com/cloud/network/NetworkVO.java index 14b643b29b7..d0209d7f916 100644 --- a/server/src/com/cloud/network/NetworkVO.java +++ b/server/src/com/cloud/network/NetworkVO.java @@ -246,6 +246,7 @@ public class NetworkVO implements Network { return state; } + // don't use this directly when possible, use Network state machine instead public void setState(State state) { this.state = state; } diff --git a/server/src/com/cloud/network/dao/NetworkDao.java b/server/src/com/cloud/network/dao/NetworkDao.java index 1fefb75a360..18dcb6f7d98 100644 --- a/server/src/com/cloud/network/dao/NetworkDao.java +++ b/server/src/com/cloud/network/dao/NetworkDao.java @@ -24,10 +24,12 @@ import com.cloud.network.Network.GuestType; import com.cloud.network.NetworkAccountVO; import com.cloud.network.NetworkVO; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.Network.State; import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.fsm.StateDao; -public interface NetworkDao extends GenericDao { +public interface NetworkDao extends GenericDao , StateDao { List listByOwner(long ownerId); diff --git a/server/src/com/cloud/network/dao/NetworkDaoImpl.java b/server/src/com/cloud/network/dao/NetworkDaoImpl.java index 29e2f818d55..2c5b46da577 100644 --- a/server/src/com/cloud/network/dao/NetworkDaoImpl.java +++ b/server/src/com/cloud/network/dao/NetworkDaoImpl.java @@ -28,6 +28,8 @@ import com.cloud.network.Network; import com.cloud.network.Network.GuestType; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; +import com.cloud.network.Network.State; +import com.cloud.network.Network.Event; import com.cloud.network.NetworkAccountDaoImpl; import com.cloud.network.NetworkAccountVO; import com.cloud.network.NetworkDomainVO; @@ -42,19 +44,18 @@ import com.cloud.offerings.dao.NetworkOfferingDaoImpl; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.utils.component.ComponentLocator; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.GenericSearchBuilder; -import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.*; import com.cloud.utils.db.JoinBuilder.JoinType; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.SequenceFetcher; -import com.cloud.utils.db.Transaction; import com.cloud.utils.net.NetUtils; +import javax.ejb.Local; +import javax.persistence.TableGenerator; +import java.util.List; +import java.util.Map; +import java.util.Random; + @Local(value = NetworkDao.class) @DB(txn = false) public class NetworkDaoImpl extends GenericDaoBase implements NetworkDao { @@ -564,6 +565,20 @@ public class NetworkDaoImpl extends GenericDaoBase implements N return customSearch(sc, null).get(0); } + @Override + public boolean updateState(State currentState, Event event, State nextState, Network vo, Object data) { + // TODO: ensure this update is correct + Transaction txn = Transaction.currentTxn(); + txn.start(); + + NetworkVO networkVo = (NetworkVO) vo; + networkVo.setState(nextState); + super.update(networkVo.getId(), networkVo); + + txn.commit(); + return true; + } + @Override public List listNetworksByAccount(long accountId, long zoneId, Network.GuestType type, boolean isSystem) { SearchCriteria sc = OfferingAccountNetworkSearch.create(); @@ -580,7 +595,6 @@ public class NetworkDaoImpl extends GenericDaoBase implements N public List listRedundantNetworks() { SearchCriteria sc = AllFieldsSearch.create(); sc.setJoinParameters("offerings", "isRedundant", true); - return listBy(sc, null); } } diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index d4958f323e4..a3f60cb65f8 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -40,7 +40,7 @@ import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; +import com.cloud.event.UsageEventUtils; import com.cloud.event.dao.EventDao; import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.InvalidParameterValueException; @@ -61,18 +61,12 @@ import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.element.FirewallServiceProvider; import com.cloud.network.element.NetworkACLServiceProvider; -import com.cloud.network.element.NetworkElement; import com.cloud.network.element.PortForwardingServiceProvider; import com.cloud.network.element.StaticNatServiceProvider; -import com.cloud.network.rules.FirewallManager; -import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.*; import com.cloud.network.rules.FirewallRule.FirewallRuleType; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRule.State; -import com.cloud.network.rules.FirewallRuleVO; -import com.cloud.network.rules.PortForwardingRule; -import com.cloud.network.rules.PortForwardingRuleVO; -import com.cloud.network.rules.StaticNat; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.vpc.VpcManager; import com.cloud.projects.Project.ListProjectResourcesCriteria; @@ -88,17 +82,18 @@ import com.cloud.utils.Ternary; import com.cloud.utils.component.Adapters; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.*; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.UserVmVO; import com.cloud.vm.dao.UserVmDao; +import org.apache.cloudstack.api.command.user.firewall.ListFirewallRulesCmd; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.util.*; @Local(value = { FirewallService.class, FirewallManager.class}) public class FirewallManagerImpl implements FirewallService, FirewallManager, NetworkRuleApplier, Manager { @@ -709,8 +704,8 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne } if (generateUsageEvent && needUsageEvent) { - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_RULE_DELETE, rule.getAccountId(), 0, rule.getId(), null); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_DELETE, rule.getAccountId(), 0, rule.getId(), + null, rule.getClass().getName(), rule.getUuid()); } txn.commit(); diff --git a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java index f8a8a95ec05..bd6305d745c 100644 --- a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java @@ -20,17 +20,16 @@ import java.util.List; import javax.ejb.Local; +import com.cloud.event.ActionEventUtils; import org.apache.log4j.Logger; import com.cloud.configuration.Config; -import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.dao.DataCenterDao; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.event.EventTypes; -import com.cloud.event.EventUtils; import com.cloud.event.EventVO; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; @@ -42,9 +41,7 @@ import com.cloud.network.NetworkVO; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.PhysicalNetwork; import com.cloud.network.PhysicalNetwork.IsolationMethod; -import com.cloud.network.PhysicalNetworkVO; import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.rules.PortForwardingRuleVO; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.offering.NetworkOffering; @@ -142,7 +139,7 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru { } implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlanTag)); - EventUtils.saveEvent(UserContext.current().getCallerUserId(), config.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: "+vnet+ " Network Id: "+config.getId(), 0); + ActionEventUtils.onCompletedActionEvent(UserContext.current().getCallerUserId(), config.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnet + " Network Id: " + config.getId(), 0); } else { vlanTag = Integer.parseInt(config.getBroadcastUri().getHost()); implemented.setBroadcastUri(config.getBroadcastUri()); diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java index 95878859598..e5371f50095 100755 --- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java @@ -19,12 +19,12 @@ package com.cloud.network.guru; import java.util.ArrayList; import java.util.List; import java.util.Random; -import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.ejb.Local; +import com.cloud.event.ActionEventUtils; import org.apache.log4j.Logger; import com.cloud.configuration.Config; @@ -36,7 +36,6 @@ import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.event.EventTypes; -import com.cloud.event.EventUtils; import com.cloud.event.EventVO; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; @@ -298,8 +297,8 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur "part of network " + network + " implement ", DataCenter.class, dcId); } implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnet)); - EventUtils.saveEvent(UserContext.current().getCallerUserId(), network.getAccountId(), - EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: "+vnet+ " Network Id: "+network.getId(), 0); + ActionEventUtils.onCompletedActionEvent(UserContext.current().getCallerUserId(), network.getAccountId(), + EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: " + vnet + " Network Id: " + network.getId(), 0); } else { implemented.setBroadcastUri(network.getBroadcastUri()); } @@ -433,9 +432,9 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur s_logger.debug("Releasing vnet for the network id=" + profile.getId()); _dcDao.releaseVnet(profile.getBroadcastUri().getHost(), profile.getDataCenterId(), profile.getPhysicalNetworkId(), profile.getAccountId(), profile.getReservationId()); - EventUtils.saveEvent(UserContext.current().getCallerUserId(), profile.getAccountId(), + ActionEventUtils.onCompletedActionEvent(UserContext.current().getCallerUserId(), profile.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_RELEASE, "Released Zone Vlan: " - +profile.getBroadcastUri().getHost()+" for Network: "+profile.getId(), 0); + + profile.getBroadcastUri().getHost() + " for Network: " + profile.getId(), 0); } profile.setBroadcastUri(null); } diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index 482c1fe9b88..8e47545974c 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -30,6 +30,7 @@ import java.util.Set; import javax.ejb.Local; import javax.naming.ConfigurationException; +import com.cloud.event.UsageEventUtils; import org.apache.cloudstack.api.command.user.loadbalancer.*; import org.apache.log4j.Logger; @@ -47,7 +48,6 @@ import com.cloud.dc.dao.VlanDao; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; import com.cloud.event.dao.EventDao; import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.InsufficientAddressCapacityException; @@ -93,7 +93,6 @@ import com.cloud.network.dao.LoadBalancerVMMapDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.element.LoadBalancingServiceProvider; -import com.cloud.network.element.NetworkElement; import com.cloud.network.lb.LoadBalancingRule.LbAutoScalePolicy; import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmGroup; import com.cloud.network.lb.LoadBalancingRule.LbAutoScaleVmProfile; @@ -871,8 +870,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa if (generateUsageEvent) { // Generate usage event right after all rules were marked for revoke - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_LOAD_BALANCER_DELETE, lb.getAccountId(), 0, lb.getId(), null); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_DELETE, lb.getAccountId(), 0, lb.getId(), + null, LoadBalancingRule.class.getName(), lb.getUuid()); } txn.commit(); @@ -1104,8 +1103,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa } s_logger.debug("Load balancer " + newRule.getId() + " for Ip address id=" + sourceIpId + ", public port " + srcPortStart + ", private port " + defPortStart + " is added successfully."); UserContext.current().setEventDetails("Load balancer Id: " + newRule.getId()); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_LOAD_BALANCER_CREATE, ipAddr.getAllocatedToAccountId(), ipAddr.getDataCenterId(), newRule.getId(), null); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_CREATE, ipAddr.getAllocatedToAccountId(), + ipAddr.getDataCenterId(), newRule.getId(), null, LoadBalancingRule.class.getName(), newRule.getUuid()); txn.commit(); return newRule; diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index fe86a8ebc99..605ffd6e794 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -20,7 +20,7 @@ import com.cloud.configuration.ConfigurationManager; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; +import com.cloud.event.UsageEventUtils; import com.cloud.event.dao.EventDao; import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.InsufficientAddressCapacityException; @@ -276,9 +276,9 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } UserContext.current().setEventDetails("Rule Id: " + newRule.getId()); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), - ipAddress.getDataCenterId(), newRule.getId(), null); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), + ipAddress.getDataCenterId(), newRule.getId(), null, PortForwardingRule.class.getName(), + newRule.getUuid()); txn.commit(); return newRule; } catch (Exception e) { @@ -358,8 +358,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } UserContext.current().setEventDetails("Rule Id: " + newRule.getId()); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), 0, newRule.getId(), null); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), 0, newRule.getId(), + null, FirewallRule.class.getName(), newRule.getUuid()); txn.commit(); StaticNatRule staticNatRule = new StaticNatRuleImpl(newRule, dstIp); diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java index b564e3d5759..5635f52c43c 100755 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -16,30 +16,6 @@ // under the License. package com.cloud.network.security; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.api.command.user.securitygroup.*; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.log4j.Logger; - import com.cloud.agent.AgentManager; import com.cloud.agent.api.NetworkRulesSystemVmCommand; import com.cloud.agent.api.SecurityGroupRulesCmd; @@ -47,33 +23,20 @@ import com.cloud.agent.api.SecurityGroupRulesCmd.IpPortAndProto; import com.cloud.agent.manager.Commands; import com.cloud.api.query.dao.SecurityGroupJoinDao; import com.cloud.api.query.vo.SecurityGroupJoinVO; - -import org.apache.cloudstack.api.command.user.securitygroup.RevokeSecurityGroupEgressCmd; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; -import com.cloud.event.dao.UsageEventDao; -import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.OperationTimedoutException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.ResourceInUseException; +import com.cloud.event.UsageEventUtils; +import com.cloud.exception.*; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkModel; import com.cloud.network.security.SecurityGroupWork.Step; import com.cloud.network.security.SecurityRule.SecurityRuleType; -import com.cloud.network.security.dao.SecurityGroupDao; -import com.cloud.network.security.dao.SecurityGroupRuleDao; -import com.cloud.network.security.dao.SecurityGroupRulesDao; -import com.cloud.network.security.dao.SecurityGroupVMMapDao; -import com.cloud.network.security.dao.SecurityGroupWorkDao; -import com.cloud.network.security.dao.VmRulesetLogDao; -import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.network.security.dao.*; import com.cloud.projects.ProjectManager; import com.cloud.server.ManagementServer; import com.cloud.tags.dao.ResourceTagDao; @@ -85,7 +48,6 @@ import com.cloud.user.dao.AccountDao; import com.cloud.uservm.UserVm; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; -import com.cloud.utils.Ternary; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; @@ -93,26 +55,26 @@ import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GlobalLock; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; -import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.StateListener; import com.cloud.utils.net.NetUtils; -import com.cloud.vm.Nic; -import com.cloud.vm.NicProfile; -import com.cloud.vm.UserVmManager; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; +import com.cloud.vm.*; import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; - import edu.emory.mathcs.backport.java.util.Collections; +import org.apache.cloudstack.api.command.user.securitygroup.*; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.util.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; @Local(value = { SecurityGroupManager.class, SecurityGroupService.class }) public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityGroupService, Manager, StateListener { @@ -159,8 +121,6 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG @Inject ProjectManager _projectMgr; @Inject - UsageEventDao _usageEventDao; - @Inject ResourceTagDao _resourceTagDao; ScheduledExecutorService _executorPool; @@ -460,8 +420,9 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG // For each group, find the security rules that allow the group for (SecurityGroupVMMapVO mapVO : groupsForVm) {// FIXME: use custom sql in the dao //Add usage events for security group assign - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SECURITY_GROUP_ASSIGN, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), mapVO.getSecurityGroupId()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SECURITY_GROUP_ASSIGN, vm.getAccountId(), + vm.getDataCenterIdToDeployIn(), vm.getId(), mapVO.getSecurityGroupId(), + vm.getClass().getName(), vm.getUuid()); List allowingRules = _securityGroupRuleDao.listByAllowedSecurityGroupId(mapVO.getSecurityGroupId()); // For each security rule that allows a group that the vm belongs to, find the group it belongs to @@ -476,8 +437,9 @@ public class SecurityGroupManagerImpl implements SecurityGroupManager, SecurityG // For each group, find the security rules rules that allow the group for (SecurityGroupVMMapVO mapVO : groupsForVm) {// FIXME: use custom sql in the dao //Add usage events for security group remove - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SECURITY_GROUP_REMOVE, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), mapVO.getSecurityGroupId()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SECURITY_GROUP_REMOVE, + vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), mapVO.getSecurityGroupId(), + vm.getClass().getName(), vm.getUuid()); List allowingRules = _securityGroupRuleDao.listByAllowedSecurityGroupId(mapVO.getSecurityGroupId()); // For each security rule that allows a group that the vm belongs to, find the group it belongs to diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java index e360bcae8ad..858c3624b3f 100755 --- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java @@ -16,44 +16,24 @@ // under the License. package com.cloud.network.vpn; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.Map; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.api.command.user.vpn.ListVpnUsersCmd; -import org.apache.log4j.Logger; - -import org.apache.cloudstack.api.command.user.vpn.ListRemoteAccessVpnsCmd; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; +import com.cloud.event.UsageEventUtils; import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.AccountLimitException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.IPAddressVO; -import com.cloud.network.Network; +import com.cloud.network.*; import com.cloud.network.Network.Service; -import com.cloud.network.NetworkModel; -import com.cloud.network.PublicIpAddress; -import com.cloud.network.RemoteAccessVpn; -import com.cloud.network.RemoteAccessVpnVO; -import com.cloud.network.VpnUser; import com.cloud.network.VpnUser.State; -import com.cloud.network.VpnUserVO; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.RemoteAccessVpnDao; import com.cloud.network.dao.VpnUserDao; -import com.cloud.network.element.NetworkElement; import com.cloud.network.element.RemoteAccessVPNServiceProvider; import com.cloud.network.rules.FirewallManager; import com.cloud.network.rules.FirewallRule; @@ -74,14 +54,19 @@ import com.cloud.utils.component.Adapters; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.*; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; import com.cloud.utils.net.NetUtils; +import org.apache.cloudstack.api.command.user.vpn.ListRemoteAccessVpnsCmd; +import org.apache.cloudstack.api.command.user.vpn.ListVpnUsersCmd; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; @Local(value = RemoteAccessVpnService.class) public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manager { @@ -281,8 +266,8 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag for(VpnUserVO user : vpnUsers){ // VPN_USER_REMOVE event is already generated for users in Revoke state if(user.getState() != VpnUser.State.Revoke){ - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), 0, user.getId(), user.getUsername()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), + 0, user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid()); } } if (vpnFwRules != null) { @@ -333,8 +318,8 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag } VpnUser user = _vpnUsersDao.persist(new VpnUserVO(vpnOwnerId, owner.getDomainId(), username, password)); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VPN_USER_ADD, user.getAccountId(), 0, user.getId(), user.getUsername()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_ADD, user.getAccountId(), 0, user.getId(), + user.getUsername(), user.getClass().getName(), user.getUuid()); txn.commit(); return user; } @@ -350,8 +335,8 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag txn.start(); user.setState(State.Revoke); _vpnUsersDao.update(user.getId(), user); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), 0, user.getId(), user.getUsername()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), 0, user.getId(), + user.getUsername(), user.getClass().getName(), user.getUuid()); txn.commit(); return true; } @@ -407,8 +392,8 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag List vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId()); for(VpnUserVO user : vpnUsers){ if(user.getState() != VpnUser.State.Revoke){ - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VPN_USER_ADD, user.getAccountId(), 0, user.getId(), user.getUsername()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_ADD, user.getAccountId(), 0, + user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid()); } } txn.commit(); @@ -483,8 +468,8 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag Transaction txn = Transaction.currentTxn(); txn.start(); _vpnUsersDao.remove(user.getId()); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), 0, user.getId(), user.getUsername()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VPN_USER_REMOVE, user.getAccountId(), + 0, user.getId(), user.getUsername(), user.getClass().getName(), user.getUuid()); txn.commit(); } s_logger.warn("Failed to apply vpn for user " + user.getUsername() + ", accountId=" + user.getAccountId()); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 40c55084ea9..0b5c53113ba 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -29,7 +29,6 @@ import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -42,6 +41,7 @@ import java.util.concurrent.TimeUnit; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; +import com.cloud.event.ActionEventUtils; import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd; import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd; import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd; @@ -60,7 +60,6 @@ import org.apache.cloudstack.api.command.user.ssh.RegisterSSHKeyPairCmd; import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd; import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd; import org.apache.cloudstack.api.command.user.vm.GetVMPasswordCmd; -import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; @@ -128,7 +127,6 @@ import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.event.EventUtils; import com.cloud.event.EventVO; import com.cloud.event.dao.EventDao; import com.cloud.exception.ConcurrentOperationException; @@ -230,7 +228,6 @@ import com.cloud.utils.net.MacAddress; import com.cloud.utils.net.NetUtils; import com.cloud.utils.ssh.SSHKeysHelper; import com.cloud.vm.ConsoleProxyVO; -import com.cloud.vm.DomainRouterVO; import com.cloud.vm.InstanceGroupVO; import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.UserVmVO; @@ -2422,12 +2419,12 @@ public class ManagementServerImpl implements ManagementServer { @Override public Long saveStartedEvent(Long userId, Long accountId, String type, String description, long startEventId) { - return EventUtils.saveStartedEvent(userId, accountId, type, description, startEventId); + return ActionEventUtils.onStartedActionEvent(userId, accountId, type, description, startEventId); } @Override public Long saveCompletedEvent(Long userId, Long accountId, String level, String type, String description, long startEventId) { - return EventUtils.saveEvent(userId, accountId, level, type, description, startEventId); + return ActionEventUtils.onCompletedActionEvent(userId, accountId, level, type, description, startEventId); } @Override diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 07f4d8ac7cb..5a799f9c87b 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -16,68 +16,14 @@ // under the License. package com.cloud.storage; -import java.math.BigDecimal; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.UnknownHostException; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.api.command.admin.storage.*; -import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; -import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; -import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; -import org.apache.log4j.Logger; - import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.BackupSnapshotCommand; -import com.cloud.agent.api.CleanupSnapshotBackupCommand; -import com.cloud.agent.api.Command; -import com.cloud.agent.api.CreateStoragePoolCommand; -import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer; -import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; -import com.cloud.agent.api.DeleteStoragePoolCommand; -import com.cloud.agent.api.ManageSnapshotCommand; -import com.cloud.agent.api.ModifyStoragePoolAnswer; -import com.cloud.agent.api.ModifyStoragePoolCommand; -import com.cloud.agent.api.UpgradeSnapshotCommand; -import com.cloud.agent.api.storage.CopyVolumeAnswer; -import com.cloud.agent.api.storage.CopyVolumeCommand; -import com.cloud.agent.api.storage.CreateAnswer; -import com.cloud.agent.api.storage.CreateCommand; -import com.cloud.agent.api.storage.DeleteTemplateCommand; -import com.cloud.agent.api.storage.DeleteVolumeCommand; -import com.cloud.agent.api.storage.DestroyCommand; -import com.cloud.agent.api.storage.ResizeVolumeCommand; -import com.cloud.agent.api.storage.ResizeVolumeAnswer; +import com.cloud.agent.api.*; +import com.cloud.agent.api.storage.*; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; -import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd; import com.cloud.async.AsyncJobManager; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityManager; @@ -104,21 +50,9 @@ import com.cloud.domain.Domain; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; +import com.cloud.event.UsageEventUtils; 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; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InsufficientStorageCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.OperationTimedoutException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceInUseException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.exception.StorageUnavailableException; +import com.cloud.exception.*; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; @@ -140,32 +74,17 @@ import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume.Event; import com.cloud.storage.Volume.Type; import com.cloud.storage.allocator.StoragePoolAllocator; -import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.SnapshotPolicyDao; -import com.cloud.storage.dao.StoragePoolDao; -import com.cloud.storage.dao.StoragePoolHostDao; -import com.cloud.storage.dao.StoragePoolWorkDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; -import com.cloud.storage.dao.VMTemplatePoolDao; -import com.cloud.storage.dao.VMTemplateS3Dao; -import com.cloud.storage.dao.VMTemplateSwiftDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.storage.dao.*; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.listener.StoragePoolMonitor; +import com.cloud.storage.listener.VolumeStateListener; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.snapshot.SnapshotScheduler; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.TemplateManager; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.User; -import com.cloud.user.UserContext; +import com.cloud.user.*; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; import com.cloud.uservm.UserVm; @@ -178,36 +97,35 @@ import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.concurrency.NamedThreadFactory; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.GenericSearchBuilder; -import com.cloud.utils.db.GlobalLock; -import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.*; import com.cloud.utils.db.JoinBuilder.JoinType; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExecutionException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.fsm.StateMachine2; -import com.cloud.vm.ConsoleProxyVO; -import com.cloud.vm.DiskProfile; -import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.SecondaryStorageVmVO; -import com.cloud.vm.UserVmManager; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; +import com.cloud.vm.*; import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.VirtualMachineManager; -import com.cloud.vm.VirtualMachineProfile; -import com.cloud.vm.VirtualMachineProfileImpl; -import com.cloud.vm.dao.ConsoleProxyDao; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.SecondaryStorageVmDao; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.dao.VMInstanceDao; +import com.cloud.vm.dao.*; +import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd; +import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd; +import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd; +import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd; +import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.math.BigDecimal; +import java.net.*; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; @Local(value = { StorageManager.class, StorageService.class }) public class StorageManagerImpl implements StorageManager, Manager, ClusterManagerListener { @@ -301,8 +219,6 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag @Inject protected ClusterDao _clusterDao; @Inject - protected UsageEventDao _usageEventDao; - @Inject protected VirtualMachineManager _vmMgr; @Inject protected DomainRouterDao _domrDao; @@ -653,9 +569,9 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag Pair volumeDetails = createVolumeFromSnapshot(volume, snapshot); if (volumeDetails != null) { createdVolume = volumeDetails.first(); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, createdVolume.getAccountId(), createdVolume.getDataCenterId(), createdVolume.getId(), createdVolume.getName(), - createdVolume.getDiskOfferingId(), null, createdVolume.getSize()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, createdVolume.getAccountId(), + createdVolume.getDataCenterId(), createdVolume.getId(), createdVolume.getName(), createdVolume.getDiskOfferingId(), + null, createdVolume.getSize(), Volume.class.getName(), createdVolume.getUuid()); } return createdVolume; } @@ -775,8 +691,9 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag volume.setPoolId(destPool.getId()); volume.setPodId(destPool.getPodId()); stateTransitTo(volume, Event.CopySucceeded); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), volume.getDiskOfferingId(), null, volume.getSize()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), + volume.getDataCenterId(), volume.getId(), volume.getName(), volume.getDiskOfferingId(), + null, volume.getSize(), Volume.class.getName(), volume.getUuid()); _volumeHostDao.remove(volumeHostVO.getId()); txn.commit(); return volume; @@ -1050,6 +967,9 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag LocalStorageSearch.join("poolHost", storageHostSearch, storageHostSearch.entity().getPoolId(), LocalStorageSearch.entity().getId(), JoinBuilder.JoinType.INNER); LocalStorageSearch.and("type", LocalStorageSearch.entity().getPoolType(), SearchCriteria.Op.IN); LocalStorageSearch.done(); + + Volume.State.getStateMachine().registerListener( new VolumeStateListener()); + return true; } @@ -1967,8 +1887,8 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag throw new InvalidParameterValueException("unable to find a snapshot with id " + snapshotId); } - if (snapshotCheck.getStatus() != Snapshot.Status.BackedUp) { - throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.Status.BackedUp + " state yet and can't be used for volume creation"); + if (snapshotCheck.getState() != Snapshot.State.BackedUp) { + throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.State.BackedUp + " state yet and can't be used for volume creation"); } diskOfferingId = snapshotCheck.getDiskOfferingId(); @@ -2058,9 +1978,10 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag volume = _volsDao.persist(volume); if(cmd.getSnapshotId() == null){ - //for volume created from snapshot, create usage event after volume creation - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), diskOfferingId, null, size); - _usageEventDao.persist(usageEvent); + //for volume created from snapshot, create usage event after volume creation + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), + volume.getDataCenterId(), volume.getId(), volume.getName(), diskOfferingId, null, size, + Volume.class.getName(), volume.getUuid()); } UserContext.current().setEventDetails("Volume Id: " + volume.getId()); @@ -2305,8 +2226,9 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag // Decrement the resource count for volumes belonging user VM's only _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); // Log usage event for volumes belonging user VM's only - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), + volume.getDataCenterId(), volume.getId(), volume.getName(), + Volume.class.getName(), volume.getUuid()); } try { @@ -2471,7 +2393,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag } // remove snapshots in Error state - List snapshots = _snapshotDao.listAllByStatus(Snapshot.Status.Error); + List snapshots = _snapshotDao.listAllByStatus(Snapshot.State.Error); for (SnapshotVO snapshotVO : snapshots) { try{ _snapshotDao.expunge(snapshotVO.getId()); @@ -3140,10 +3062,9 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag // Save usage event and update resource count for user vm volumes if (vm instanceof UserVm) { - - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size); - _usageEventDao.persist(usageEvent); - + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), + vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size, + Volume.class.getName(), vol.getUuid()); _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); } return toDiskProfile(vol, offering); @@ -3204,9 +3125,9 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag offeringId = offering.getId(); } - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, template.getId(), - vol.getSize()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), + vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, template.getId(), + vol.getSize(), Volume.class.getName(), vol.getUuid()); _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume); } diff --git a/server/src/com/cloud/storage/dao/SnapshotDao.java b/server/src/com/cloud/storage/dao/SnapshotDao.java index b32d2782b6a..3b961f6fa89 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDao.java +++ b/server/src/com/cloud/storage/dao/SnapshotDao.java @@ -16,15 +16,16 @@ // under the License. package com.cloud.storage.dao; -import java.util.List; - import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot.Type; import com.cloud.storage.SnapshotVO; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDao; +import com.cloud.utils.fsm.StateDao; -public interface SnapshotDao extends GenericDao { +import java.util.List; + +public interface SnapshotDao extends GenericDao, StateDao { List listByVolumeId(long volumeId); List listByVolumeId(Filter filter, long volumeId); SnapshotVO findNextSnapshot(long parentSnapId); @@ -39,7 +40,7 @@ public interface SnapshotDao extends GenericDao { List listByHostId(Filter filter, long hostId); List listByHostId(long hostId); public Long countSnapshotsForAccount(long accountId); - List listByInstanceId(long instanceId, Snapshot.Status... status); - List listByStatus(long volumeId, Snapshot.Status... status); - List listAllByStatus(Snapshot.Status... status); + List listByInstanceId(long instanceId, Snapshot.State... status); + List listByStatus(long volumeId, Snapshot.State... status); + List listAllByStatus(Snapshot.State... status); } diff --git a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java index 65e2f5f1d76..3fe1aba5a98 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -16,33 +16,27 @@ // under the License. package com.cloud.storage.dao; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.util.List; - -import javax.ejb.Local; - -import org.apache.log4j.Logger; - import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.storage.Snapshot; +import com.cloud.storage.Snapshot.Event; +import com.cloud.storage.Snapshot.State; import com.cloud.storage.Snapshot.Type; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.utils.component.ComponentLocator; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.*; import com.cloud.utils.db.JoinBuilder.JoinType; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; -import com.cloud.utils.db.Transaction; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.VMInstanceDaoImpl; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.List; @Local (value={SnapshotDao.class}) public class SnapshotDaoImpl extends GenericDaoBase implements SnapshotDao { @@ -113,7 +107,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements public List listByHostId(Filter filter, long hostId ) { SearchCriteria sc = HostIdSearch.create(); sc.setParameters("hostId", hostId); - sc.setParameters("status", Snapshot.Status.BackedUp); + sc.setParameters("status", Snapshot.State.BackedUp); return listBy(sc, filter); } @@ -145,7 +139,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements HostIdSearch = createSearchBuilder(); HostIdSearch.and("hostId", HostIdSearch.entity().getSecHostId(), SearchCriteria.Op.EQ); - HostIdSearch.and("status", HostIdSearch.entity().getStatus(), SearchCriteria.Op.EQ); + HostIdSearch.and("status", HostIdSearch.entity().getState(), SearchCriteria.Op.EQ); HostIdSearch.done(); VolumeIdTypeSearch = createSearchBuilder(); @@ -172,7 +166,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements StatusSearch = createSearchBuilder(); StatusSearch.and("volumeId", StatusSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); - StatusSearch.and("status", StatusSearch.entity().getStatus(), SearchCriteria.Op.IN); + StatusSearch.and("status", StatusSearch.entity().getState(), SearchCriteria.Op.IN); StatusSearch.done(); CountSnapshotsByAccount = createSearchBuilder(Long.class); @@ -182,7 +176,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements CountSnapshotsByAccount.done(); InstanceIdSearch = createSearchBuilder(); - InstanceIdSearch.and("status", InstanceIdSearch.entity().getStatus(), SearchCriteria.Op.IN); + InstanceIdSearch.and("status", InstanceIdSearch.entity().getState(), SearchCriteria.Op.IN); SearchBuilder instanceSearch = _instanceDao.createSearchBuilder(); instanceSearch.and("instanceId", instanceSearch.entity().getId(), SearchCriteria.Op.EQ); @@ -274,7 +268,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements } @Override - public List listByInstanceId(long instanceId, Snapshot.Status... status) { + public List listByInstanceId(long instanceId, Snapshot.State... status) { SearchCriteria sc = this.InstanceIdSearch.create(); if (status != null && status.length != 0) { @@ -287,7 +281,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements } @Override - public List listByStatus(long volumeId, Snapshot.Status... status) { + public List listByStatus(long volumeId, Snapshot.State... status) { SearchCriteria sc = this.StatusSearch.create(); sc.setParameters("volumeId", volumeId); sc.setParameters("status", (Object[])status); @@ -309,9 +303,20 @@ public class SnapshotDaoImpl extends GenericDaoBase implements } @Override - public List listAllByStatus(Snapshot.Status... status) { + public List listAllByStatus(Snapshot.State... status) { SearchCriteria sc = this.StatusSearch.create(); sc.setParameters("status", (Object[])status); return listBy(sc, null); } + + @Override + public boolean updateState(State currentState, Event event, State nextState, Snapshot snapshot, Object data) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + SnapshotVO snapshotVO = (SnapshotVO)snapshot; + snapshotVO.setStatus(nextState); + super.update(snapshotVO.getId(), snapshotVO); + txn.commit(); + return true; + } } diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 27367779650..cf51567c951 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -16,36 +16,14 @@ // under the License. package com.cloud.storage.download; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.Timer; -import java.util.concurrent.ConcurrentHashMap; - -import javax.ejb.Local; - -import org.apache.log4j.Logger; - import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; -import com.cloud.agent.api.storage.DeleteTemplateCommand; -import com.cloud.agent.api.storage.DeleteVolumeCommand; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.ListVolumeAnswer; -import com.cloud.agent.api.storage.ListVolumeCommand; +import com.cloud.agent.api.storage.*; import com.cloud.agent.api.storage.DownloadCommand.Proxy; import com.cloud.agent.api.storage.DownloadCommand.ResourceType; -import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; -import com.cloud.agent.api.storage.ListTemplateAnswer; -import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.configuration.Config; @@ -54,8 +32,7 @@ import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; -import com.cloud.event.dao.UsageEventDao; +import com.cloud.event.UsageEventUtils; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.StorageUnavailableException; @@ -65,26 +42,9 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.resource.ResourceManager; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.StorageManager; -import com.cloud.storage.SwiftVO; -import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc; -import com.cloud.storage.Volume; -import com.cloud.storage.VolumeHostVO; -import com.cloud.storage.VolumeVO; +import com.cloud.storage.*; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.Volume.Event; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.dao.StoragePoolHostDao; -import com.cloud.storage.dao.SwiftDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; -import com.cloud.storage.dao.VMTemplatePoolDao; -import com.cloud.storage.dao.VMTemplateSwiftDao; -import com.cloud.storage.dao.VMTemplateZoneDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.storage.dao.*; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.template.TemplateConstants; @@ -92,19 +52,21 @@ import com.cloud.storage.template.TemplateInfo; import com.cloud.user.Account; import com.cloud.user.ResourceLimitService; import com.cloud.utils.component.Inject; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.*; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.fsm.NoTransitionException; import com.cloud.vm.SecondaryStorageVm; import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.UserVmManager; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.SecondaryStorageVmDao; import edu.emory.mathcs.backport.java.util.Collections; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; @Local(value={DownloadMonitor.class}) @@ -147,11 +109,6 @@ public class DownloadMonitorImpl implements DownloadMonitor { ConfigurationDao _configDao; @Inject UserVmManager _vmMgr; - - - @Inject - private UsageEventDao _usageEventDao; - @Inject private ClusterDao _clusterDao; @Inject @@ -517,8 +474,9 @@ public class DownloadMonitorImpl implements DownloadMonitor { eventType = EventTypes.EVENT_ISO_CREATE; } if(template.getAccountId() != Account.ACCOUNT_ID_SYSTEM){ - UsageEventVO usageEvent = new UsageEventVO(eventType, template.getAccountId(), host.getDataCenterId(), template.getId(), template.getName(), null, template.getSourceTemplateId() , size); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(eventType, template.getAccountId(), host.getDataCenterId(), + template.getId(), template.getName(), null, template.getSourceTemplateId(), size, + template.getClass().getName(), template.getUuid()); } } txn.commit(); @@ -550,8 +508,8 @@ public class DownloadMonitorImpl implements DownloadMonitor { } String eventType = EventTypes.EVENT_VOLUME_UPLOAD; if(volume.getAccountId() != Account.ACCOUNT_ID_SYSTEM){ - UsageEventVO usageEvent = new UsageEventVO(eventType, volume.getAccountId(), host.getDataCenterId(), volume.getId(), volume.getName(), null, 0l , size); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(eventType, volume.getAccountId(), host.getDataCenterId(), + volume.getId(), volume.getName(), null, 0l, size, volume.getClass().getName(), volume.getUuid()); } }else if (dnldStatus == Status.DOWNLOAD_ERROR || dnldStatus == Status.ABANDONED || dnldStatus == Status.UNKNOWN){ //Decrement the volume count diff --git a/server/src/com/cloud/storage/listener/SnapshotStateListener.java b/server/src/com/cloud/storage/listener/SnapshotStateListener.java new file mode 100644 index 00000000000..2b19887e83a --- /dev/null +++ b/server/src/com/cloud/storage/listener/SnapshotStateListener.java @@ -0,0 +1,85 @@ +package com.cloud.storage.listener; + +import com.cloud.event.EventCategory; +import com.cloud.storage.Snapshot; +import com.cloud.storage.Snapshot.Event; +import com.cloud.storage.Snapshot.State; +import com.cloud.server.ManagementServer; +import com.cloud.utils.component.Adapters; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.fsm.StateListener; +import org.apache.cloudstack.framework.events.EventBus; +import org.apache.cloudstack.framework.events.EventBusException; +import org.apache.log4j.Logger; + +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +public class SnapshotStateListener implements StateListener { + + // get the event bus provider if configured + protected static EventBus _eventBus = null; + static { + Adapters eventBusImpls = ComponentLocator.getLocator(ManagementServer.Name).getAdapters(EventBus.class); + if (eventBusImpls != null) { + Enumeration eventBusenum = eventBusImpls.enumeration(); + if (eventBusenum != null && eventBusenum.hasMoreElements()) { + _eventBus = eventBusenum.nextElement(); // configure event bus if configured + } + } + } + + private static final Logger s_logger = Logger.getLogger(VolumeStateListener.class); + + public SnapshotStateListener() { + + } + + @Override + public boolean preStateTransitionEvent(State oldState, Event event, State newState, Snapshot vo, boolean status, Object opaque) { + pubishOnEventBus(event.name(), "preStateTransitionEvent", vo, oldState, newState); + return true; + } + + @Override + public boolean postStateTransitionEvent(State oldState, Event event, State newState, Snapshot vo, boolean status, Object opaque) { + pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState); + return true; + } + + private void pubishOnEventBus(String event, String status, Snapshot vo, State oldState, State newState) { + + if (_eventBus == null) { + return; // no provider is configured to provide events bus, so just return + } + + String resourceName = getEntityFromClassName(Snapshot.class.getName()); + org.apache.cloudstack.framework.events.Event eventMsg = new org.apache.cloudstack.framework.events.Event( + ManagementServer.Name, + EventCategory.RESOURCE_STATE_CHANGE_EVENT.getName(), + event, + resourceName, + vo.getUuid()); + Map eventDescription = new HashMap(); + eventDescription.put("resource", resourceName); + eventDescription.put("id", vo.getUuid()); + eventDescription.put("old-state", oldState.name()); + eventDescription.put("new-state", newState.name()); + eventMsg.setDescription(eventDescription); + try { + _eventBus.publish(eventMsg); + } catch (EventBusException e) { + s_logger.warn("Failed to publish state change event on the the event bus."); + } + } + + private String getEntityFromClassName(String entityClassName) { + int index = entityClassName.lastIndexOf("."); + String entityName = entityClassName; + if (index != -1) { + entityName = entityClassName.substring(index+1); + } + return entityName; + } +} diff --git a/server/src/com/cloud/storage/listener/VolumeStateListener.java b/server/src/com/cloud/storage/listener/VolumeStateListener.java new file mode 100644 index 00000000000..c460016f90a --- /dev/null +++ b/server/src/com/cloud/storage/listener/VolumeStateListener.java @@ -0,0 +1,85 @@ +package com.cloud.storage.listener; + +import com.cloud.event.EventCategory; +import com.cloud.storage.Volume; +import com.cloud.storage.Volume.Event; +import com.cloud.storage.Volume.State; +import com.cloud.server.ManagementServer; +import com.cloud.utils.component.Adapters; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.fsm.StateListener; +import org.apache.cloudstack.framework.events.EventBus; +import org.apache.cloudstack.framework.events.EventBusException; +import org.apache.log4j.Logger; + +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +public class VolumeStateListener implements StateListener { + + // get the event bus provider if configured + protected static EventBus _eventBus = null; + static { + Adapters eventBusImpls = ComponentLocator.getLocator(ManagementServer.Name).getAdapters(EventBus.class); + if (eventBusImpls != null) { + Enumeration eventBusenum = eventBusImpls.enumeration(); + if (eventBusenum != null && eventBusenum.hasMoreElements()) { + _eventBus = eventBusenum.nextElement(); // configure event bus if configured + } + } + } + + private static final Logger s_logger = Logger.getLogger(VolumeStateListener.class); + + public VolumeStateListener() { + + } + + @Override + public boolean preStateTransitionEvent(State oldState, Event event, State newState, Volume vo, boolean status, Object opaque) { + pubishOnEventBus(event.name(), "preStateTransitionEvent", vo, oldState, newState); + return true; + } + + @Override + public boolean postStateTransitionEvent(State oldState, Event event, State newState, Volume vo, boolean status, Object opaque) { + pubishOnEventBus(event.name(), "postStateTransitionEvent", vo, oldState, newState); + return true; + } + + private void pubishOnEventBus(String event, String status, Volume vo, State oldState, State newState) { + + if (_eventBus == null) { + return; // no provider is configured to provide events bus, so just return + } + + String resourceName = getEntityFromClassName(Volume.class.getName()); + org.apache.cloudstack.framework.events.Event eventMsg = new org.apache.cloudstack.framework.events.Event( + ManagementServer.Name, + EventCategory.RESOURCE_STATE_CHANGE_EVENT.getName(), + event, + resourceName, + vo.getUuid()); + Map eventDescription = new HashMap(); + eventDescription.put("resource", resourceName); + eventDescription.put("id", vo.getUuid()); + eventDescription.put("old-state", oldState.name()); + eventDescription.put("new-state", newState.name()); + eventMsg.setDescription(eventDescription); + try { + _eventBus.publish(eventMsg); + } catch (EventBusException e) { + s_logger.warn("Failed to state change event on the the event bus."); + } + } + + private String getEntityFromClassName(String entityClassName) { + int index = entityClassName.lastIndexOf("."); + String entityName = entityClassName; + if (index != -1) { + entityName = entityClassName.substring(index+1); + } + return entityName; + } +} diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 15d8c53d06f..66eb8e16b21 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -16,37 +16,12 @@ // under the License. package com.cloud.storage.snapshot; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd; -import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd; -import org.apache.log4j.Logger; - import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.BackupSnapshotAnswer; -import com.cloud.agent.api.BackupSnapshotCommand; -import com.cloud.agent.api.Command; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; -import com.cloud.agent.api.DeleteSnapshotsDirCommand; -import com.cloud.agent.api.DownloadSnapshotFromS3Command; -import com.cloud.agent.api.ManageSnapshotAnswer; -import com.cloud.agent.api.ManageSnapshotCommand; -import com.cloud.agent.api.downloadSnapshotFromSwiftCommand; +import com.cloud.agent.api.*; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.alert.AlertManager; -import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd; import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd; -import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd; import com.cloud.configuration.Config; import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; @@ -55,11 +30,7 @@ import com.cloud.dc.DataCenter; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.domain.dao.DomainDao; -import com.cloud.event.ActionEvent; -import com.cloud.event.EventTypes; -import com.cloud.event.EventUtils; -import com.cloud.event.EventVO; -import com.cloud.event.UsageEventVO; +import com.cloud.event.*; import com.cloud.event.dao.EventDao; import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.InvalidParameterValueException; @@ -69,44 +40,21 @@ import com.cloud.exception.StorageUnavailableException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.PhysicalNetworkTrafficType; import com.cloud.org.Grouping; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.resource.ResourceManager; import com.cloud.server.ResourceTag.TaggedResourceType; -import com.cloud.storage.Snapshot; -import com.cloud.storage.Snapshot.Status; +import com.cloud.storage.*; import com.cloud.storage.Snapshot.Type; -import com.cloud.storage.SnapshotPolicyVO; -import com.cloud.storage.SnapshotScheduleVO; -import com.cloud.storage.SnapshotVO; -import com.cloud.storage.Storage; import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.SnapshotPolicyDao; -import com.cloud.storage.dao.SnapshotScheduleDao; -import com.cloud.storage.dao.StoragePoolDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.dao.*; +import com.cloud.storage.listener.SnapshotStateListener; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.AccountVO; -import com.cloud.user.DomainManager; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.User; -import com.cloud.user.UserContext; +import com.cloud.user.*; import com.cloud.user.dao.AccountDao; import com.cloud.utils.DateUtil; import com.cloud.utils.DateUtil.IntervalType; @@ -116,18 +64,24 @@ import com.cloud.utils.Ternary; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.*; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.fsm.NoTransitionException; +import com.cloud.utils.fsm.StateMachine2; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.UserVmDao; +import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd; +import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd; +import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd; +import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.util.*; @Local(value = { SnapshotManager.class, SnapshotService.class }) public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Manager { @@ -195,6 +149,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma private int _deltaSnapshotMax; private int _backupsnapshotwait; + private StateMachine2 _snapshotFsm; + protected SearchBuilder PolicySnapshotSearch; protected SearchBuilder PoliciesForSnapSearch; @@ -259,6 +215,13 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (snapshot == null) { throw new CloudRuntimeException("Can not find snapshot " + snapshotId); } + + try { + stateTransitTo(snapshot, Snapshot.Event.CreateRequested); + } catch (NoTransitionException nte) { + s_logger.debug("Failed to update snapshot state due to " + nte.getMessage()); + } + // Send a ManageSnapshotCommand to the agent String vmName = _storageMgr.getVmNameOnVolume(volume); long volumeId = volume.getId(); @@ -289,14 +252,16 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (preSnapshotPath != null && preSnapshotPath.equals(answer.getSnapshotPath())) { // empty snapshot s_logger.debug("CreateSnapshot: this is empty snapshot "); - snapshot.setPath(preSnapshotPath); - snapshot.setBackupSnapshotId(preSnapshotVO.getBackupSnapshotId()); - snapshot.setSwiftId(preSnapshotVO.getSwiftId()); - - snapshot.setStatus(Snapshot.Status.BackedUp); - snapshot.setPrevSnapshotId(preId); - snapshot.setSecHostId(preSnapshotVO.getSecHostId()); - _snapshotDao.update(snapshotId, snapshot); + try { + snapshot.setPath(preSnapshotPath); + snapshot.setBackupSnapshotId(preSnapshotVO.getBackupSnapshotId()); + snapshot.setSwiftId(preSnapshotVO.getSwiftId()); + snapshot.setPrevSnapshotId(preId); + snapshot.setSecHostId(preSnapshotVO.getSecHostId()); + stateTransitTo(snapshot, Snapshot.Event.OperationNotPerformed); + } catch (NoTransitionException nte) { + s_logger.debug("CreateSnapshot: failed to update state of snapshot due to " + nte.getMessage()); + } } else { long preSnapshotId = 0; @@ -346,6 +311,11 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (answer != null) { s_logger.error(answer.getDetails()); } + try { + stateTransitTo(snapshot, Snapshot.Event.OperationFailed); + } catch (NoTransitionException nte) { + s_logger.debug("Failed to update snapshot state due to " + nte.getMessage()); + } throw new CloudRuntimeException("Creating snapshot for volume " + volumeId + " on primary storage failed."); } @@ -410,7 +380,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } if(userVm.getHypervisorType() == HypervisorType.VMware || userVm.getHypervisorType() == HypervisorType.KVM) { - List activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.Status.Creating, Snapshot.Status.CreatedOnPrimary, Snapshot.Status.BackingUp); + List activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp); if(activeSnapshots.size() > 1) throw new CloudRuntimeException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later"); } @@ -419,19 +389,15 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma snapshot = createSnapshotOnPrimary(volume, policyId, snapshotId); if (snapshot != null) { - if (snapshot.getStatus() == Snapshot.Status.CreatedOnPrimary) { + if (snapshot.getState() == Snapshot.State.CreatedOnPrimary) { backedUp = backupSnapshotToSecondaryStorage(snapshot); - } else if (snapshot.getStatus() == Snapshot.Status.BackedUp) { + } else if (snapshot.getState() == Snapshot.State.BackedUp) { // For empty snapshot we set status to BackedUp in createSnapshotOnPrimary backedUp = true; } else { - snapshot.setStatus(Status.Error); - _snapshotDao.update(snapshot.getId(), snapshot); throw new CloudRuntimeException("Failed to create snapshot: " + snapshot + " on primary storage"); } if (!backedUp) { - snapshot.setStatus(Status.Error); - _snapshotDao.update(snapshot.getId(), snapshot); throw new CloudRuntimeException("Created snapshot: " + snapshot + " on primary but failed to backup on secondary"); } } else { @@ -444,23 +410,15 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma //Check if the snapshot was removed while backingUp. If yes, do not log snapshot create usage event SnapshotVO freshSnapshot = _snapshotDao.findById(snapshot.getId()); if ((freshSnapshot != null) && backedUp) { - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, - volume.getSize()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), + snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, + volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid()); } if( !backedUp ) { - snapshot.setStatus(Status.Error); - _snapshotDao.update(snapshot.getId(), snapshot); } else { _resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot); } - } else { - snapshot = _snapshotDao.findById(snapshotId); - if (snapshot != null) { - snapshot.setStatus(Status.Error); - _snapshotDao.update(snapshotId, snapshot); - } } /* @@ -478,9 +436,12 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma private SnapshotVO updateDBOnCreate(Long id, String snapshotPath, long preSnapshotId) { SnapshotVO createdSnapshot = _snapshotDao.findByIdIncludingRemoved(id); createdSnapshot.setPath(snapshotPath); - createdSnapshot.setStatus(Snapshot.Status.CreatedOnPrimary); createdSnapshot.setPrevSnapshotId(preSnapshotId); - _snapshotDao.update(id, createdSnapshot); + try { + stateTransitTo(createdSnapshot, Snapshot.Event.OperationSucceeded); + } catch (NoTransitionException nte) { + s_logger.debug("Faile to update state of snapshot due to " + nte.getMessage()); + } return createdSnapshot; } @@ -622,9 +583,11 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma throw new CloudRuntimeException("Can not acquire lock for snapshot: " + ss); } try { - - snapshot.setStatus(Snapshot.Status.BackingUp); - _snapshotDao.update(snapshot.getId(), snapshot); + try { + stateTransitTo(snapshot, Snapshot.Event.BackupToSecondary); + } catch (NoTransitionException nte) { + s_logger.debug("Failed to update the state of snapshot while backing up snapshot"); + } long volumeId = snapshot.getVolumeId(); VolumeVO volume = _volsDao.lockRow(volumeId, true); @@ -705,10 +668,18 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma if (answer.isFull()) { snapshot.setPrevSnapshotId(0); } - snapshot.setStatus(Snapshot.Status.BackedUp); - _snapshotDao.update(snapshotId, snapshot); + try { + stateTransitTo(snapshot, Snapshot.Event.OperationSucceeded); + } catch (NoTransitionException nte) { + s_logger.debug("Failed to update the state of snapshot while backing up snapshot"); + } } else { + try { + stateTransitTo(snapshot, Snapshot.Event.OperationFailed); + } catch (NoTransitionException nte) { + s_logger.debug("Failed to update the state of snapshot while backing up snapshot"); + } s_logger.warn("Failed to back up snapshot on secondary storage, deleting the record from the DB"); _snapshotDao.remove(snapshotId); } @@ -766,8 +737,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma long oldSnapId = oldestSnapshot.getId(); s_logger.debug("Max snaps: " + policy.getMaxSnaps() + " exceeded for snapshot policy with Id: " + policyId + ". Deleting oldest snapshot: " + oldSnapId); if(deleteSnapshotInternal(oldSnapId)){ - //log Snapshot delete event - EventUtils.saveEvent(User.UID_SYSTEM, oldestSnapshot.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_SNAPSHOT_DELETE, "Successfully deleted oldest snapshot: " + oldSnapId, 0); + //log Snapshot delete event + ActionEventUtils.onCompletedActionEvent(User.UID_SYSTEM, oldestSnapshot.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_SNAPSHOT_DELETE, "Successfully deleted oldest snapshot: " + oldSnapId, 0); } snaps.remove(oldestSnapshot); } @@ -787,7 +758,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma _accountMgr.checkAccess(caller, null, true, snapshotCheck); - if( !Status.BackedUp.equals(snapshotCheck.getStatus() ) ) { + if( !Snapshot.State.BackedUp.equals(snapshotCheck.getState() ) ) { throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is not in BackedUp Status"); } @@ -812,9 +783,10 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma Transaction txn = Transaction.currentTxn(); txn.start(); _snapshotDao.remove(snapshotId); - if (snapshot.getStatus() == Snapshot.Status.BackedUp) { - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, 0L); - _usageEventDao.persist(usageEvent); + if (snapshot.getState() == Snapshot.State.BackedUp) { + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), + snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, 0L, + snapshot.getClass().getName(), snapshot.getUuid()); } _resourceLimitMgr.decrementResourceCount(snapshot.getAccountId(), ResourceType.snapshot); txn.commit(); @@ -966,7 +938,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma SearchBuilder sb = _snapshotDao.createSearchBuilder(); _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); - sb.and("status", sb.entity().getStatus(), SearchCriteria.Op.EQ); + sb.and("status", sb.entity().getState(), SearchCriteria.Op.EQ); sb.and("volumeId", sb.entity().getVolumeId(), SearchCriteria.Op.EQ); sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); @@ -1115,9 +1087,9 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma } // Log event after successful deletion - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), volume.getDataCenterId(), snapshot.getId(), snapshot.getName(), null, null, - volume.getSize()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_DELETE, snapshot.getAccountId(), + volume.getDataCenterId(), snapshot.getId(), snapshot.getName(), null, null, + volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid()); } } } @@ -1452,6 +1424,9 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma s_logger.info("Snapshot Manager is configured."); + _snapshotFsm = Snapshot.State.getStateMachine(); + _snapshotFsm.registerListener(new SnapshotStateListener()); + return true; } @@ -1538,11 +1513,15 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma @Override public boolean canOperateOnVolume(VolumeVO volume) { - List snapshots = _snapshotDao.listByStatus(volume.getId(), Status.Creating, Status.CreatedOnPrimary, Status.BackingUp); + List snapshots = _snapshotDao.listByStatus(volume.getId(), Snapshot.State.Creating, + Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp); if (snapshots.size() > 0) { return false; } return true; } + protected boolean stateTransitTo(Snapshot snapshot, Snapshot.Event e) throws NoTransitionException { + return _snapshotFsm.transitTo(snapshot, e, null, _snapshotDao); + } } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java index d7deb6fa74b..93898938c60 100644 --- a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java @@ -26,6 +26,7 @@ import java.util.TimerTask; import javax.ejb.Local; import javax.naming.ConfigurationException; +import com.cloud.event.ActionEventUtils; import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotCmd; import org.apache.log4j.Logger; @@ -39,7 +40,6 @@ import com.cloud.async.AsyncJobVO; import com.cloud.async.dao.AsyncJobDao; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.event.EventTypes; -import com.cloud.event.EventUtils; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotPolicyVO; import com.cloud.storage.SnapshotScheduleVO; @@ -232,8 +232,8 @@ public class SnapshotSchedulerImpl implements SnapshotScheduler { tmpSnapshotScheduleVO = _snapshotScheduleDao.acquireInLockTable(snapshotScheId); - Long eventId = EventUtils.saveScheduledEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, - EventTypes.EVENT_SNAPSHOT_CREATE, "creating snapshot for volume Id:"+volumeId,0); + Long eventId = ActionEventUtils.onScheduledActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, + EventTypes.EVENT_SNAPSHOT_CREATE, "creating snapshot for volume Id:" + volumeId, 0); Map params = new HashMap(); params.put(ApiConstants.VOLUME_ID, "" + volumeId); diff --git a/server/src/com/cloud/template/HyervisorTemplateAdapter.java b/server/src/com/cloud/template/HyervisorTemplateAdapter.java index c80d1de0fbf..81a482b73f5 100755 --- a/server/src/com/cloud/template/HyervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HyervisorTemplateAdapter.java @@ -16,28 +16,13 @@ // under the License. package com.cloud.template; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.UnknownHostException; -import java.util.List; - -import javax.ejb.Local; - -import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; -import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd; -import org.apache.log4j.Logger; - import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.DeleteTemplateCommand; -import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd; -import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.DataCenterVO; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; +import com.cloud.event.UsageEventUtils; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.host.HostVO; @@ -53,6 +38,15 @@ import com.cloud.user.Account; import com.cloud.utils.component.Inject; import com.cloud.utils.db.DB; import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; +import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd; +import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd; +import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import java.net.*; +import java.util.List; @Local(value=TemplateAdapter.class) public class HyervisorTemplateAdapter extends TemplateAdapterBase implements TemplateAdapter { @@ -202,8 +196,7 @@ public class HyervisorTemplateAdapter extends TemplateAdapterBase implements Tem success = false; break; } - UsageEventVO usageEvent = new UsageEventVO(eventType, account.getId(), sZoneId, templateId, null); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); templateHostVO.setDestroyed(true); _tmpltHostDao.update(templateHostVO.getId(), templateHostVO); String installPath = templateHostVO.getInstallPath(); diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 1372111eac3..42106b3bdb5 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -16,41 +16,14 @@ // under the License. package com.cloud.template; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd; -import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd; -import org.apache.cloudstack.api.command.user.iso.*; -import org.apache.cloudstack.api.command.user.template.*; -import org.apache.log4j.Logger; - -import org.apache.cloudstack.acl.SecurityChecker.AccessType; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand; -import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.to.SwiftTO; -import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd; -import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; +import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobVO; import com.cloud.configuration.Config; @@ -63,7 +36,7 @@ import com.cloud.dc.dao.DataCenterDao; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; +import com.cloud.event.UsageEventUtils; import com.cloud.event.dao.EventDao; import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.InvalidParameterValueException; @@ -77,51 +50,19 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuruManager; import com.cloud.projects.Project; import com.cloud.projects.ProjectManager; -import com.cloud.storage.LaunchPermissionVO; -import com.cloud.storage.SnapshotVO; -import com.cloud.storage.Storage; +import com.cloud.storage.*; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolHostVO; -import com.cloud.storage.StoragePoolStatus; -import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.Upload; import com.cloud.storage.Upload.Type; -import com.cloud.storage.UploadVO; -import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateStoragePoolVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.VMTemplateSwiftVO; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.LaunchPermissionDao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.StoragePoolDao; -import com.cloud.storage.dao.StoragePoolHostDao; -import com.cloud.storage.dao.UploadDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; -import com.cloud.storage.dao.VMTemplatePoolDao; -import com.cloud.storage.dao.VMTemplateS3Dao; -import com.cloud.storage.dao.VMTemplateSwiftDao; -import com.cloud.storage.dao.VMTemplateZoneDao; -import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.dao.*; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.upload.UploadMonitor; import com.cloud.template.TemplateAdapter.TemplateAdapterType; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.AccountService; -import com.cloud.user.AccountVO; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.UserContext; +import com.cloud.user.*; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserAccountDao; import com.cloud.user.dao.UserDao; @@ -132,12 +73,7 @@ import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.concurrency.NamedThreadFactory; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.GlobalLock; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.*; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.UserVmManager; import com.cloud.vm.UserVmVO; @@ -145,6 +81,21 @@ import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd; +import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd; +import org.apache.cloudstack.api.command.user.iso.*; +import org.apache.cloudstack.api.command.user.template.*; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.net.*; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; @Local(value={TemplateManager.class, TemplateService.class}) @@ -823,8 +774,8 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe _tmpltDao.addTemplateToZone(template, dstZoneId); if(account.getId() != Account.ACCOUNT_ID_SYSTEM){ - UsageEventVO usageEvent = new UsageEventVO(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltHost.getSize()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltHost.getSize(), + template.getClass().getName(), template.getUuid()); } return true; } diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index b910a03f99b..f60d305ff21 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -36,6 +36,7 @@ import javax.crypto.spec.SecretKeySpec; import javax.ejb.Local; import javax.naming.ConfigurationException; +import com.cloud.event.ActionEventUtils; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.SecurityChecker; @@ -64,7 +65,6 @@ import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.event.EventUtils; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.CloudAuthenticationException; import com.cloud.exception.ConcurrentOperationException; @@ -1744,7 +1744,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag public void logoutUser(Long userId) { UserAccount userAcct = _userAccountDao.findById(userId); if (userAcct != null) { - EventUtils.saveEvent(userId, userAcct.getAccountId(), userAcct.getDomainId(), EventTypes.EVENT_USER_LOGOUT, "user has logged out"); + ActionEventUtils.onActionEvent(userId, userAcct.getAccountId(), userAcct.getDomainId(), EventTypes.EVENT_USER_LOGOUT, "user has logged out"); } // else log some kind of error event? This likely means the user doesn't exist, or has been deleted... } @@ -1875,10 +1875,10 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag s_logger.debug("User: " + username + " in domain " + domainId + " has successfully logged in"); } if (NetUtils.isValidIp(loginIpAddress)) { - EventUtils.saveEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN, + ActionEventUtils.onActionEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN, "user has logged in from IP Address " + loginIpAddress); } else { - EventUtils.saveEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN, + ActionEventUtils.onActionEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN, "user has logged in. The IP Address cannot be determined"); } return user; diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 3737450674d..969539c0b15 100644 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -54,7 +54,7 @@ import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; +import com.cloud.event.UsageEventUtils; import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.*; import com.cloud.ha.HighAvailabilityManager; @@ -245,8 +245,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager @Inject protected LoadBalancingRulesManager _lbMgr; @Inject - protected UsageEventDao _usageEventDao; - @Inject protected SSHKeyPairDao _sshKeyPairDao; @Inject protected UserVmDetailsDao _vmDetailsDao; @@ -280,6 +278,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager PhysicalNetworkDao _physicalNetworkDao; @Inject VpcManager _vpcMgr; + @Inject + UsageEventDao _usageEventDao; protected ScheduledExecutorService _executor = null; protected int _expungeInterval; @@ -841,7 +841,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } @Override - @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true) + @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true) public Volume detachVolumeFromVM(DetachVolumeCmd cmmd) { Account caller = UserContext.current().getCaller(); if ((cmmd.getId() == null && cmmd.getDeviceId() == null && cmmd.getVirtualMachineId() == null) || (cmmd.getId() != null && (cmmd.getDeviceId() != null || cmmd.getVirtualMachineId() != null)) @@ -1372,9 +1372,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager offeringId = offering.getId(); } } - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), offeringId, templateId, - volume.getSize()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), + volume.getDataCenterId(), volume.getId(), volume.getName(), offeringId, templateId, + volume.getSize(), Volume.class.getName(), volume.getUuid()); } } @@ -1640,8 +1640,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager //check permissions _accountMgr.checkAccess(caller, null, true, snapshot); - if (snapshot.getStatus() != Snapshot.Status.BackedUp) { - throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.Status.BackedUp + " state yet and can't be used for template creation"); + if (snapshot.getState() != Snapshot.State.BackedUp) { + throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.State.BackedUp + " state yet and can't be used for template creation"); } /* @@ -1888,9 +1888,10 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager templateHostVO.setPhysicalSize(answer.getphysicalSize()); _templateHostDao.persist(templateHostVO); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), secondaryStorageHost.getDataCenterId(), privateTemplate.getId(), - privateTemplate.getName(), null, privateTemplate.getSourceTemplateId(), templateHostVO.getSize()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), + secondaryStorageHost.getDataCenterId(), privateTemplate.getId(), + privateTemplate.getName(), null, privateTemplate.getSourceTemplateId(), + templateHostVO.getSize(), VirtualMachineTemplate.class.getName(), privateTemplate.getUuid()); txn.commit(); } } finally { @@ -2835,8 +2836,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } UserContext.current().setEventDetails("Vm Id: " + vm.getId()); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(), hypervisorType.toString()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, accountId, zone.getId(), vm.getId(), + vm.getHostName(), offering.getId(), template.getId(), hypervisorType.toString(), + VirtualMachine.class.getName(), vm.getUuid()); _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm); txn.commit(); @@ -3006,8 +3008,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager for (NicVO nic : nics) { NetworkVO network = _networkDao.findById(nic.getNetworkId()); long isDefault = (nic.isDefaultNic()) ? 1 : 0; - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName(), network.getNetworkOfferingId(), null, isDefault); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), + vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName(), network.getNetworkOfferingId(), + null, isDefault, VirtualMachine.class.getName(), vm.getUuid()); if (network.getTrafficType() == TrafficType.Guest) { originalIp = nic.getIp4Address(); guestNic = nic; @@ -3270,8 +3273,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager List volumes = _volsDao.findByInstance(vmId); for (VolumeVO volume : volumes) { if (volume.getVolumeType().equals(Volume.Type.ROOT)) { - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName()); - _usageEventDao.persist(usageEvent); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), + volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(), + volume.getUuid()); } } @@ -3721,8 +3725,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager Transaction txn = Transaction.currentTxn(); txn.start(); //generate destroy vm event for usage - _usageEventDao.persist(new UsageEventVO(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), - vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString())); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), + vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(), + VirtualMachine.class.getName(), vm.getUuid()); // update resource counts _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.user_vm); @@ -3734,13 +3739,16 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager // OS 2: update volume List volumes = _volsDao.findByInstance(cmd.getVmId()); for (VolumeVO volume : volumes) { - _usageEventDao.persist(new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName())); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), + volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(), volume.getUuid()); _resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume); volume.setAccountId(newAccount.getAccountId()); _volsDao.persist(volume); _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume); - _usageEventDao.persist(new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), - volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize())); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), + volume.getDataCenterId(), volume.getId(), volume.getName(), + volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), + volume.getUuid()); //snapshots: mark these removed in db List snapshots = _snapshotDao.listByVolumeIdIncludingRemoved(volume.getId()); for (SnapshotVO snapshot: snapshots){ @@ -3750,8 +3758,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager _resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.user_vm); //generate usage events to account for this change - _usageEventDao.persist(new UsageEventVO(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), - vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString())); + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), + vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(), + VirtualMachine.class.getName(), vm.getUuid()); txn.commit(); diff --git a/server/src/com/cloud/vm/UserVmStateListener.java b/server/src/com/cloud/vm/UserVmStateListener.java index 4d9bcc563fd..786387ffe03 100644 --- a/server/src/com/cloud/vm/UserVmStateListener.java +++ b/server/src/com/cloud/vm/UserVmStateListener.java @@ -16,24 +16,48 @@ // under the License. package com.cloud.vm; -import java.util.List; - +import com.cloud.event.EventCategory; import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventVO; +import com.cloud.event.UsageEventUtils; import com.cloud.event.dao.UsageEventDao; +import com.cloud.network.Network; import com.cloud.network.NetworkVO; import com.cloud.network.dao.NetworkDao; +import com.cloud.server.ManagementServer; +import com.cloud.utils.component.Adapters; +import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.fsm.StateListener; import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.NicDao; +import org.apache.cloudstack.framework.events.EventBus; +import org.apache.cloudstack.framework.events.EventBusException; +import org.apache.log4j.Logger; + +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class UserVmStateListener implements StateListener { protected UsageEventDao _usageEventDao; protected NetworkDao _networkDao; protected NicDao _nicDao; - + private static final Logger s_logger = Logger.getLogger(UserVmStateListener.class); + + // get the event bus provider if configured + protected static EventBus _eventBus = null; + static { + Adapters eventBusImpls = ComponentLocator.getLocator(ManagementServer.Name).getAdapters(EventBus.class); + if (eventBusImpls != null) { + Enumeration eventBusenum = eventBusImpls.enumeration(); + if (eventBusenum != null && eventBusenum.hasMoreElements()) { + _eventBus = eventBusenum.nextElement(); // configure event bus if configured + } + } + } + public UserVmStateListener(UsageEventDao usageEventDao, NetworkDao networkDao, NicDao nicDao) { this._usageEventDao = usageEventDao; this._networkDao = networkDao; @@ -42,6 +66,7 @@ public class UserVmStateListener implements StateListener nics = _nicDao.listByVmId(vo.getId()); for (NicVO nic : nics) { NetworkVO network = _networkDao.findById(nic.getNetworkId()); - usageEvent = new UsageEventVO(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), null, network.getNetworkOfferingId(), null, 0L); - _usageEventDao.persist(usageEvent); + UsageEventUtils.saveUsageEvent(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), null, network.getNetworkOfferingId(), null, 0L); } } else if (VirtualMachine.State.isVmDestroyed(oldState, event, newState)) { - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_DESTROY, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), vo.getHostName(), vo.getServiceOfferingId(), + UsageEventUtils.saveUsageEvent(EventTypes.EVENT_VM_DESTROY, vo.getAccountId(), vo.getDataCenterIdToDeployIn(), vo.getId(), vo.getHostName(), vo.getServiceOfferingId(), vo.getTemplateId(), vo.getHypervisorType().toString()); - _usageEventDao.persist(usageEvent); } return true; } + + private void pubishOnEventBus(String event, String status, VirtualMachine vo, VirtualMachine.State oldState, VirtualMachine.State newState) { + + if (_eventBus == null) { + return; // no provider is configured to provide events bus, so just return + } + + String resourceName = getEntityFromClassName(Network.class.getName()); + org.apache.cloudstack.framework.events.Event eventMsg = new org.apache.cloudstack.framework.events.Event( + ManagementServer.Name, + EventCategory.RESOURCE_STATE_CHANGE_EVENT.getName(), + event, + resourceName, + vo.getUuid()); + Map eventDescription = new HashMap(); + eventDescription.put("resource", resourceName); + eventDescription.put("id", vo.getUuid()); + eventDescription.put("old-state", oldState.name()); + eventDescription.put("new-state", newState.name()); + eventMsg.setDescription(eventDescription); + try { + _eventBus.publish(eventMsg); + } catch (EventBusException e) { + s_logger.warn("Failed to publish state change event on the the event bus."); + } + + } + + private String getEntityFromClassName(String entityClassName) { + int index = entityClassName.lastIndexOf("."); + String entityName = entityClassName; + if (index != -1) { + entityName = entityClassName.substring(index+1); + } + return entityName; + } } diff --git a/server/test/com/cloud/snapshot/SnapshotDaoTest.java b/server/test/com/cloud/snapshot/SnapshotDaoTest.java index c412f49b3d4..5dc9b9182ea 100644 --- a/server/test/com/cloud/snapshot/SnapshotDaoTest.java +++ b/server/test/com/cloud/snapshot/SnapshotDaoTest.java @@ -16,24 +16,23 @@ // under the License. package com.cloud.snapshot; -import java.util.List; - import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.dao.SnapshotDaoImpl; import com.cloud.utils.component.ComponentLocator; - import junit.framework.Assert; import junit.framework.TestCase; +import java.util.List; + public class SnapshotDaoTest extends TestCase { public void testListBy() { SnapshotDaoImpl dao = ComponentLocator.inject(SnapshotDaoImpl.class); - List snapshots = dao.listByInstanceId(3, Snapshot.Status.BackedUp); + List snapshots = dao.listByInstanceId(3, Snapshot.State.BackedUp); for(SnapshotVO snapshot : snapshots) { - Assert.assertTrue(snapshot.getStatus() == Snapshot.Status.BackedUp); + Assert.assertTrue(snapshot.getState() == Snapshot.State.BackedUp); } } } diff --git a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java index 7c9a5823516..f0e4b54115f 100644 --- a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java +++ b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java @@ -16,12 +16,7 @@ // under the License. package com.cloud.vpc.dao; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.ejb.Local; - +import com.cloud.network.Network; import com.cloud.network.Network.GuestType; import com.cloud.network.NetworkAccountVO; import com.cloud.network.NetworkVO; @@ -31,6 +26,11 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; +import javax.ejb.Local; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + @Local(value = NetworkDao.class) @DB(txn = false) public class MockNetworkDaoImpl extends GenericDaoBase implements NetworkDao{ @@ -342,6 +342,11 @@ public class MockNetworkDaoImpl extends GenericDaoBase implemen return 0; } + @Override + public boolean updateState(Network.State currentState, Network.Event event, Network.State nextState, Network vo, Object data) { + return true; + } + /* (non-Javadoc) * @see com.cloud.network.dao.NetworkDao#listNetworksByAccount(long, long, com.cloud.network.Network.GuestType, boolean) */ diff --git a/tools/whisker/LICENSE b/tools/whisker/LICENSE index 7efac5c566a..025cb33136b 100644 --- a/tools/whisker/LICENSE +++ b/tools/whisker/LICENSE @@ -748,7 +748,7 @@ Within the deps/awsapi-lib directory The Covered Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial - computer software" (as that term is defined at 48 C.F.R. ¤ + computer software" (as that term is defined at 48 C.F.R. � 252.227-7014(a)(1)) and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 @@ -1138,7 +1138,7 @@ Within the deps/awsapi-lib directory The Covered Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial - computer software" (as that term is defined at 48 C.F.R. ¤ + computer software" (as that term is defined at 48 C.F.R. � 252.227-7014(a)(1)) and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 @@ -1526,7 +1526,7 @@ Within the deps/awsapi-lib directory The Covered Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial - computer software" (as that term is defined at 48 C.F.R. ¤ + computer software" (as that term is defined at 48 C.F.R. � 252.227-7014(a)(1)) and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 @@ -1867,7 +1867,9 @@ Within the deps/awsapi-lib directory slf4j-api-1.5.11.jar from https://github.com/qos-ch/slf4j slf4j-jdk14-1.5.11.jar from https://github.com/qos-ch/slf4j - licensed under the Mozilla Public License, Version 1.0 http://www.mozilla.org/MPL/1.1/ (as follows) + + licensed under the Mozilla Public License, Version 1.1 http://www.mozilla.org/MPL/1.1/ (as follows) + MOZILLA PUBLIC LICENSE @@ -2344,6 +2346,486 @@ Within the deps/awsapi-lib directory from Shigeru Chiba http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/ javassist-3.9.0.GA.jar from http://sourceforge.net/projects/jboss/files/Javassist/ + + licensed under the Mozilla Public License, Version 1.1 http://www.mozilla.org/MPL/1.1/ (as follows) + + Copyright (c) 2007-2012 VMware, Inc. All Rights Reserved. + + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + + 1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + + 2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + + 3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + + 4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + + 5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + + 6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + + 7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + + 8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + + 9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + + 10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + + 11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + + 12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + + 13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + + EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (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.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is RabbitMQ. + + The Initial Developer of the Original Code is VMware, Ltd.. + Portions created by VMware, Ltd. are Copyright (C) + 2007-2012 VMware, Inc.. All Rights Reserved. + + Contributor(s): . + + Alternatively, the contents of this file may be used under the terms + of the GNU General Public License Version 2 license (the "[GPL] License"), in which case the + provisions of [GPL] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [GPL] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [GPL] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [GPL] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + + + from VMware, Inc http://www.vmware.com/ + rabbitmq-client.jar from http://www.rabbitmq.com/java-client.html + + Within the patches/systemvm/debian/config/etc directory placed in the public domain by Adiscon GmbH http://www.adiscon.com/ @@ -2980,7 +3462,7 @@ Within the target/jar directory The Covered Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial - computer software" (as that term is defined at 48 C.F.R. ¤ + computer software" (as that term is defined at 48 C.F.R. � 252.227-7014(a)(1)) and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 @@ -3369,7 +3851,7 @@ Within the target/jar directory The Covered Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial - computer software" (as that term is defined at 48 C.F.R. ¤ + computer software" (as that term is defined at 48 C.F.R. � 252.227-7014(a)(1)) and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 @@ -3895,7 +4377,7 @@ Within the target/jar directory licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) - Copyright (C) 2008 Tóth István + Copyright (C) 2008 T�th Istv�n 2008-2012 Daniel Veillard 2009-2011 Bryan Kearney @@ -4026,7 +4508,7 @@ Within the ui/lib directory licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) - Copyright (c) 2006 - 2011 Jörn Zaefferer + Copyright (c) 2006 - 2011 J�rn Zaefferer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -4221,7 +4703,7 @@ Within the ui/lib/jquery-ui directory Within the ui/lib/qunit directory licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) - Copyright (c) 2012 John Resig, Jörn Zaefferer + Copyright (c) 2012 John Resig, J�rn Zaefferer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/tools/whisker/descriptor-for-packaging.xml b/tools/whisker/descriptor-for-packaging.xml index 0144dbc055b..29a8284686b 100644 --- a/tools/whisker/descriptor-for-packaging.xml +++ b/tools/whisker/descriptor-for-packaging.xml @@ -2423,6 +2423,10 @@ Innovation Centre, 2006 (http://www.it-innovation.soton.ac.uk). id='adiscon.com' name='Adiscon GmbH' url='http://www.adiscon.com/' /> + Copyright (c) 2013 The Apache Software Foundation @@ -2948,5 +2952,19 @@ Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + + Copyright (c) 2007-2012 VMware, Inc. All Rights Reserved. + + PROJECTRabbitMQ + INITIAL_DEVELOPERVMware, Ltd. + INITIAL_DEVELOPER_COPYRIGHT2007-2012 VMware, Inc. + CONTRIBUTORS + ALT_LIC_NAMEGNU General Public License Version 2 + ALT_LIC_SHORTGPL + + + + +