From a1ab3364f4b22efe1138dbabfc43936dd8bcd82a Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Wed, 11 Jun 2014 15:22:13 -0700 Subject: [PATCH] CLOUDSTACK-6895: 1. Populate firstclass entities as uuids in the context instead of dbids for performance. 2. Add ctxDetails in the ParamGenericValidationWorker to avoid warning for api validation 3. Add some missing events. 4. Correcting mapping for ResourceObjectType.NetworkACL and ResourceObjectType.NetworkACLItem (cherry picked from commit 8a9092c3cd4e3c034f9f4d0a7491875dc080e9dc) Conflicts: api/src/com/cloud/event/EventTypes.java api/src/org/apache/cloudstack/api/BaseCmd.java --- api/src/com/cloud/event/EventTypes.java | 42 +++++++++------- .../apache/cloudstack/api/ApiConstants.java | 1 + .../org/apache/cloudstack/api/BaseCmd.java | 48 ++++++++++++++++++- server/src/com/cloud/api/ApiServer.java | 8 +--- .../ParamGenericValidationWorker.java | 1 + .../api/dispatch/ParamProcessWorker.java | 2 +- .../src/com/cloud/event/ActionEventUtils.java | 32 ++++++++----- .../network/vpc/NetworkACLManagerImpl.java | 1 - .../network/vpc/NetworkACLServiceImpl.java | 1 + .../network/vpn/Site2SiteVpnManagerImpl.java | 5 +- .../cloud/tags/TaggedResourceManagerImpl.java | 4 +- 11 files changed, 103 insertions(+), 42 deletions(-) diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index d9aa3f45f69..5c20dbf9c09 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -19,9 +19,6 @@ package com.cloud.event; import java.util.HashMap; import java.util.Map; -import com.cloud.server.ResourceTag; -import com.cloud.vm.ConsoleProxy; -import com.cloud.vm.SecondaryStorageVm; import org.apache.cloudstack.config.Configuration; import com.cloud.dc.DataCenter; @@ -37,14 +34,20 @@ import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PhysicalNetworkTrafficType; import com.cloud.network.PublicIpAddress; import com.cloud.network.RemoteAccessVpn; +import com.cloud.network.Site2SiteCustomerGateway; +import com.cloud.network.Site2SiteVpnConnection; +import com.cloud.network.Site2SiteVpnGateway; import com.cloud.network.as.AutoScaleCounter; import com.cloud.network.as.AutoScalePolicy; import com.cloud.network.as.AutoScaleVmGroup; import com.cloud.network.as.AutoScaleVmProfile; import com.cloud.network.as.Condition; import com.cloud.network.router.VirtualRouter; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.HealthCheckPolicy; import com.cloud.network.rules.LoadBalancer; import com.cloud.network.rules.StaticNat; +import com.cloud.network.rules.StickinessPolicy; import com.cloud.network.security.SecurityGroup; import com.cloud.network.vpc.PrivateGateway; import com.cloud.network.vpc.StaticRoute; @@ -53,6 +56,7 @@ import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; import com.cloud.projects.Project; +import com.cloud.server.ResourceTag; import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOSHypervisor; import com.cloud.storage.Snapshot; @@ -60,6 +64,8 @@ import com.cloud.storage.Volume; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.user.User; +import com.cloud.vm.ConsoleProxy; +import com.cloud.vm.SecondaryStorageVm; import com.cloud.vm.VirtualMachine; public class EventTypes { @@ -548,12 +554,16 @@ public class EventTypes { entityEventDetails.put(EVENT_FIREWALL_CLOSE, Network.class); // Load Balancers - entityEventDetails.put(EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, LoadBalancer.class); - entityEventDetails.put(EVENT_REMOVE_FROM_LOAD_BALANCER_RULE, LoadBalancer.class); + entityEventDetails.put(EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, FirewallRule.class); + entityEventDetails.put(EVENT_REMOVE_FROM_LOAD_BALANCER_RULE, FirewallRule.class); entityEventDetails.put(EVENT_LOAD_BALANCER_CREATE, LoadBalancer.class); - entityEventDetails.put(EVENT_LOAD_BALANCER_DELETE, LoadBalancer.class); - entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_CREATE, LoadBalancer.class); - entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_DELETE, LoadBalancer.class); + entityEventDetails.put(EVENT_LOAD_BALANCER_DELETE, FirewallRule.class); + entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_CREATE, StickinessPolicy.class); + entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_UPDATE, StickinessPolicy.class); + entityEventDetails.put(EVENT_LB_STICKINESSPOLICY_DELETE, StickinessPolicy.class); + entityEventDetails.put(EVENT_LB_HEALTHCHECKPOLICY_CREATE, HealthCheckPolicy.class); + entityEventDetails.put(EVENT_LB_HEALTHCHECKPOLICY_UPDATE, HealthCheckPolicy.class); + entityEventDetails.put(EVENT_LB_HEALTHCHECKPOLICY_DELETE, HealthCheckPolicy.class); entityEventDetails.put(EVENT_LOAD_BALANCER_UPDATE, LoadBalancer.class); entityEventDetails.put(EVENT_LB_CERT_UPLOAD, LoadBalancer.class); entityEventDetails.put(EVENT_LB_CERT_DELETE, LoadBalancer.class); @@ -693,14 +703,14 @@ public class EventTypes { entityEventDetails.put(EVENT_REMOTE_ACCESS_VPN_DESTROY, RemoteAccessVpn.class); entityEventDetails.put(EVENT_VPN_USER_ADD, RemoteAccessVpn.class); entityEventDetails.put(EVENT_VPN_USER_REMOVE, RemoteAccessVpn.class); - entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_CREATE, RemoteAccessVpn.class); - entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_DELETE, RemoteAccessVpn.class); - entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE, RemoteAccessVpn.class); - entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE, RemoteAccessVpn.class); - entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE, RemoteAccessVpn.class); - entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_CREATE, RemoteAccessVpn.class); - entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_DELETE, RemoteAccessVpn.class); - entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_RESET, RemoteAccessVpn.class); + entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_CREATE, Site2SiteVpnGateway.class); + entityEventDetails.put(EVENT_S2S_VPN_GATEWAY_DELETE, Site2SiteVpnGateway.class); + entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_CREATE, Site2SiteCustomerGateway.class); + entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_DELETE, Site2SiteCustomerGateway.class); + entityEventDetails.put(EVENT_S2S_VPN_CUSTOMER_GATEWAY_UPDATE, Site2SiteCustomerGateway.class); + entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_CREATE, Site2SiteVpnConnection.class); + entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_DELETE, Site2SiteVpnConnection.class); + entityEventDetails.put(EVENT_S2S_VPN_CONNECTION_RESET, Site2SiteVpnConnection.class); // Custom certificates entityEventDetails.put(EVENT_UPLOAD_CUSTOM_CERTIFICATE, "Certificate"); diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 850e67e64b9..5e9c973c130 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -58,6 +58,7 @@ public class ApiConstants { public static final String CPU_SPEED = "cpuspeed"; public static final String CREATED = "created"; public static final String CTX_ACCOUNT_ID = "ctxaccountid"; + public static final String CTX_DETAILS = "ctxDetails"; public static final String CTX_USER_ID = "ctxuserid"; public static final String CTXSTARTEVENTID = "ctxstarteventid"; public static final String CTX_START_EVENT_ID = "ctxStartEventId"; diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java index 6a4b4a8f3a5..ac9a20866af 100644 --- a/api/src/org/apache/cloudstack/api/BaseCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseCmd.java @@ -361,6 +361,52 @@ public abstract class BaseCmd { * @return display flag */ public boolean isDisplay(){ - return true; + CallContext context = CallContext.current(); + Map contextMap = context.getContextParameters(); + boolean isDisplay = true; + + // Iterate over all the first class entities in context and check their display property. + for(Map.Entry entry : contextMap.entrySet()){ + try{ + Object key = entry.getKey(); + Class clz = Class.forName((String)key); + if(Displayable.class.isAssignableFrom(clz)){ + final Object objVO = getEntityVO(clz, entry.getValue()); + isDisplay = ((Displayable) objVO).isDisplay(); + } + + // If the flag is false break immediately + if(!isDisplay) + break; + } catch (Exception e){ + s_logger.trace("Caught exception while checking first class entities for display property, continuing on", e); + } + } + + context.setEventDisplayEnabled(isDisplay); + return isDisplay; + } + + private Object getEntityVO(Class entityType, Object entityId){ + + // entityId can be internal db id or UUID so accordingly call findbyId or findByUUID + + if (entityId instanceof Long){ + // Its internal db id - use findById + return _entityMgr.findById(entityType, (Long)entityId); + } else if(entityId instanceof String){ + try{ + // In case its an async job the internal db id would be a string because of json deserialization + Long internalId = Long.valueOf((String) entityId); + return _entityMgr.findById(entityType, internalId); + } catch (NumberFormatException e){ + // It is uuid - use findByUuid` + return _entityMgr.findByUuid(entityType, (String)entityId); + } + } + + return null; + } + } diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 18eb4d96f30..4da271487ab 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -617,7 +617,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer params.put("id", objectId.toString()); Class entityClass = EventTypes.getEntityClassForEvent(createCmd.getEventType()); if (entityClass != null) - ctx.putContextParameter(entityClass.getName(), objectId); + ctx.putContextParameter(entityClass.getName(), objectUuid); } else { // Extract the uuid before params are processed and id reflects internal db id objectUuid = params.get(ApiConstants.ID); @@ -639,12 +639,6 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer long startEventId = ctx.getStartEventId(); asyncCmd.setStartEventId(startEventId); - // Add the resource id in the call context, also add some other first class object ids (for now vm) if available. - // TODO - this should be done for all the uuids passed in the cmd - so should be moved where uuid to id conversion happens. - if (EventTypes.getEntityForEvent(asyncCmd.getEventType()) != null) { - ctx.putContextParameter(EventTypes.getEntityForEvent(asyncCmd.getEventType()), objectUuid); - } - // save the scheduled event final Long eventId = ActionEventUtils.onScheduledActionEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(), diff --git a/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java b/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java index d6b0cf26bf8..7aaafbb55fc 100644 --- a/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java +++ b/server/src/com/cloud/api/dispatch/ParamGenericValidationWorker.java @@ -63,6 +63,7 @@ public class ParamGenericValidationWorker implements DispatchWorker { defaultParamNames.add(ApiConstants.CTX_ACCOUNT_ID); defaultParamNames.add(ApiConstants.CTX_START_EVENT_ID); defaultParamNames.add(ApiConstants.CTX_USER_ID); + defaultParamNames.add(ApiConstants.CTX_DETAILS); defaultParamNames.add(ApiConstants.UUID); defaultParamNames.add(ApiConstants.ID); defaultParamNames.add("_"); diff --git a/server/src/com/cloud/api/dispatch/ParamProcessWorker.java b/server/src/com/cloud/api/dispatch/ParamProcessWorker.java index 0bb02200392..1592b93fe22 100644 --- a/server/src/com/cloud/api/dispatch/ParamProcessWorker.java +++ b/server/src/com/cloud/api/dispatch/ParamProcessWorker.java @@ -427,7 +427,7 @@ public class ParamProcessWorker implements DispatchWorker { } // Return on first non-null Id for the uuid entity if (internalId != null){ - CallContext.current().putContextParameter(entity.getName(), internalId); + CallContext.current().putContextParameter(entity.getName(), uuid); break; } } diff --git a/server/src/com/cloud/event/ActionEventUtils.java b/server/src/com/cloud/event/ActionEventUtils.java index 363bb93b4d7..72c3b8f9087 100755 --- a/server/src/com/cloud/event/ActionEventUtils.java +++ b/server/src/com/cloud/event/ActionEventUtils.java @@ -206,8 +206,7 @@ public class ActionEventUtils { //Get uuid from id if(context.getContextParameter(entityClass.getName()) != null){ try { - final Object objVO = s_entityMgr.findByIdIncludingRemoved(entityClass, getInternalId(context.getContextParameter(entityClass.getName()))); - entityUuid = ((Identity)objVO).getUuid(); + entityUuid = getEntityUuid(entityClass, context.getContextParameter(entityClass.getName())); } catch (Exception e){ s_logger.debug("Caught exception while finding entityUUID, moving on"); } @@ -250,17 +249,27 @@ public class ActionEventUtils { } } - private static Long getInternalId(Object internalIdObj){ - Long internalId = null; + private static String getEntityUuid(Class entityType, Object entityId){ - // In case its an async job the value would be a string because of json deserialization - if(internalIdObj instanceof String){ - internalId = Long.valueOf((String) internalIdObj); - }else if (internalIdObj instanceof Long){ - internalId = (Long) internalIdObj; + // entityId can be internal db id or UUID so accordingly call findbyId or return uuid directly + + if (entityId instanceof Long){ + // Its internal db id - use findById + final Object objVO = s_entityMgr.findById(entityType, (Long)entityId); + return ((Identity)objVO).getUuid(); + } else if(entityId instanceof String){ + try{ + // In case its an async job the internal db id would be a string because of json deserialization + Long internalId = Long.valueOf((String) entityId); + final Object objVO = s_entityMgr.findById(entityType, internalId); + return ((Identity)objVO).getUuid(); + } catch (NumberFormatException e){ + // It is uuid - so return it + return (String)entityId; + } } - return internalId; + return null; } private static long getDomainId(long accountId) { @@ -282,8 +291,7 @@ public class ActionEventUtils { Object key = entry.getKey(); Class clz = Class.forName((String)key); if(clz instanceof Class && Identity.class.isAssignableFrom(clz)){ - final Object objVO = s_entityMgr.findById(clz, getInternalId(entry.getValue())); - String uuid = ((Identity) objVO).getUuid(); + String uuid = getEntityUuid(clz, entry.getValue()); eventDescription.put(ReflectUtil.getEntityName(clz), uuid); } } diff --git a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java index d808c3fbc9f..de0465b8e76 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java @@ -271,7 +271,6 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana } @Override - @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_DELETE, eventDescription = "revoking network acl", async = true) public boolean revokeNetworkACLItem(long ruleId) { NetworkACLItemVO rule = _networkACLItemDao.findById(ruleId); diff --git a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java index 19a26c16277..23b0ccde914 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java @@ -206,6 +206,7 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ } @Override + @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_DELETE, eventDescription = "Deleting Network ACL List", async = true) public boolean deleteNetworkACL(long id) { Account caller = CallContext.current().getCallingAccount(); NetworkACL acl = _networkACLDao.findById(id); diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index e6d0b1233f1..8edab625541 100644 --- a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -119,7 +119,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn } @Override - @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_GATEWAY_CREATE, eventDescription = "creating s2s vpn gateway", create = true) + @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_GATEWAY_CREATE, eventDescription = "creating s2s vpn gateway", async = true) public Site2SiteVpnGateway createVpnGateway(CreateVpnGatewayCmd cmd) { Account caller = CallContext.current().getCallingAccount(); Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId()); @@ -311,6 +311,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn @Override @DB + @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_CONNECTION_CREATE, eventDescription = "starting s2s vpn connection", async = true) public Site2SiteVpnConnection startVpnConnection(long id) throws ResourceUnavailableException { Site2SiteVpnConnectionVO conn = _vpnConnectionDao.acquireInLockTable(id); if (conn == null) { @@ -387,7 +388,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn } @Override - @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_GATEWAY_DELETE, eventDescription = "deleting s2s vpn gateway", create = true) + @ActionEvent(eventType = EventTypes.EVENT_S2S_VPN_GATEWAY_DELETE, eventDescription = "deleting s2s vpn gateway", async = true) public boolean deleteVpnGateway(DeleteVpnGatewayCmd cmd) { CallContext.current().setEventDetails(" Id: " + cmd.getId()); Account caller = CallContext.current().getCallingAccount(); diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index 2ccab0bf01c..e6f317cd02f 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -106,7 +106,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso s_typeMap.put(ResourceObjectType.Project, ProjectVO.class); s_typeMap.put(ResourceObjectType.Vpc, VpcVO.class); s_typeMap.put(ResourceObjectType.Nic, NicVO.class); - s_typeMap.put(ResourceObjectType.NetworkACL, NetworkACLVO.class); + s_typeMap.put(ResourceObjectType.NetworkACL, NetworkACLItemVO.class); s_typeMap.put(ResourceObjectType.StaticRoute, StaticRouteVO.class); s_typeMap.put(ResourceObjectType.VMSnapshot, VMSnapshotVO.class); s_typeMap.put(ResourceObjectType.RemoteAccessVpn, RemoteAccessVpnVO.class); @@ -114,7 +114,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso s_typeMap.put(ResourceObjectType.ServiceOffering, ServiceOfferingVO.class); s_typeMap.put(ResourceObjectType.Storage, StoragePoolVO.class); s_typeMap.put(ResourceObjectType.PrivateGateway, RemoteAccessVpnVO.class); - s_typeMap.put(ResourceObjectType.NetworkACLList, NetworkACLItemVO.class); + s_typeMap.put(ResourceObjectType.NetworkACLList, NetworkACLVO.class); s_typeMap.put(ResourceObjectType.VpnGateway, Site2SiteVpnGatewayVO.class); s_typeMap.put(ResourceObjectType.CustomerGateway, Site2SiteCustomerGatewayVO.class); s_typeMap.put(ResourceObjectType.VpnConnection, Site2SiteVpnConnectionVO.class);