From 33a0dec965c96483c8cd55e309250662fca5e2da Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Mon, 10 Mar 2014 16:22:34 -0700 Subject: [PATCH] CLOUDSTACK-6221: Publish first class objects involved in an operation (for now vm uuid) on the event bus . Example - during attach/detachIso along with iso id, vm id should be available as well. --- api/src/com/cloud/event/EventTypes.java | 1 + server/src/com/cloud/api/ApiDispatcher.java | 9 ++++++++- server/src/com/cloud/api/ApiServer.java | 11 ++++++++++- server/src/com/cloud/event/ActionEventUtils.java | 8 +++++++- utils/src/com/cloud/utils/ReflectUtil.java | 13 +++++++++++++ 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 7994adab82e..a5fc0f0f7d3 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -483,6 +483,7 @@ public class EventTypes { // TODO: need a way to force author adding event types to declare the entity details as well, with out braking // current ActionEvent annotation semantics + // TODO #2 - The map should be from event type to class. entityEventDetails = new HashMap(); diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index 8f980d99038..27ff9521974 100755 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -22,6 +22,8 @@ import javax.annotation.PostConstruct; import javax.inject.Inject; import com.cloud.event.EventTypes; +import com.cloud.utils.ReflectUtil; +import com.cloud.vm.VirtualMachine; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseAsyncCmd; import org.apache.cloudstack.api.BaseAsyncCreateCmd; @@ -83,13 +85,18 @@ public class ApiDispatcher { final BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmd; final String startEventId = params.get(ApiConstants.CTX_START_EVENT_ID); - String uuid = params.get("uuid"); + String uuid = params.get(ApiConstants.UUID); ctx.setStartEventId(Long.valueOf(startEventId)); // Fow now use the key from EventTypes.java rather than getInstanceType bcz the later doesn't refer to the interfaces + // 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()), uuid); } + if(params.get(ApiConstants.VIRTUAL_MACHINE_ID) != null){ + ctx.putContextParameter(ReflectUtil.getEntityName(VirtualMachine.class), params.get(ApiConstants.VIRTUAL_MACHINE_ID)); + } // Synchronise job on the object if needed if (asyncCmd.getJob() != null && asyncCmd.getSyncObjId() != null && asyncCmd.getSyncObjType() != null) { diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 7ad7c106952..35026897d79 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -54,6 +54,8 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.cloud.event.EventTypes; +import com.cloud.utils.ReflectUtil; +import com.cloud.vm.VirtualMachine; import org.apache.cloudstack.acl.APIChecker; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -503,6 +505,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer final CallContext ctx = CallContext.current(); final Long callerUserId = ctx.getCallingUserId(); final Account caller = ctx.getCallingAccount(); + String vmUUID = params.get(ApiConstants.VIRTUAL_MACHINE_ID); // Queue command based on Cmd super class: // BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned. @@ -519,7 +522,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer params.put("id", objectId.toString()); } else { // Extract the uuid before params are processed and id reflects internal db id - objectUuid = params.get("id"); + objectUuid = params.get(ApiConstants.ID); dispatchChainFactory.getStandardDispatchChain().dispatch(new DispatchTask(cmdObj, params)); } @@ -538,9 +541,15 @@ 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); } + if(vmUUID != null){ + ctx.putContextParameter(ReflectUtil.getEntityName(VirtualMachine.class), vmUUID); + } + // 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/event/ActionEventUtils.java b/server/src/com/cloud/event/ActionEventUtils.java index 59546708bce..28e5680b630 100755 --- a/server/src/com/cloud/event/ActionEventUtils.java +++ b/server/src/com/cloud/event/ActionEventUtils.java @@ -25,6 +25,8 @@ import java.util.Map; import javax.annotation.PostConstruct; import javax.inject.Inject; +import com.cloud.utils.ReflectUtil; +import com.cloud.vm.VirtualMachine; import org.apache.log4j.Logger; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -186,10 +188,12 @@ public class ActionEventUtils { String entityType = null; String entityUuid = null; CallContext context = CallContext.current(); + String vmEntityName = ReflectUtil.getEntityName(VirtualMachine.class); + String vmuuid = (String) context.getContextParameter(vmEntityName); Class entityKey = getEntityKey(eventType); if (entityKey != null) { - //FIXME - Remove this + //FIXME - Remove this since it should be covered by the else if condition below. entityUuid = (String)context.getContextParameter(entityKey); if (entityUuid != null) entityType = entityKey.getName(); @@ -220,6 +224,8 @@ public class ActionEventUtils { eventDescription.put("status", state.toString()); eventDescription.put("entity", entityType); eventDescription.put("entityuuid", entityUuid); + //Put all the first class entities that are touched during the action. For now atleast put in the vmid. + eventDescription.put(vmEntityName, vmuuid); eventDescription.put("description", description); String eventDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").format(new Date()); diff --git a/utils/src/com/cloud/utils/ReflectUtil.java b/utils/src/com/cloud/utils/ReflectUtil.java index 379f1c0bd27..9c09980e0fc 100755 --- a/utils/src/com/cloud/utils/ReflectUtil.java +++ b/utils/src/com/cloud/utils/ReflectUtil.java @@ -189,4 +189,17 @@ public class ReflectUtil { } + public static String getEntityName(Class clz){ + if(clz == null) + return null; + + String entityName = clz.getName(); + int index = entityName.lastIndexOf("."); + if (index != -1) { + return entityName.substring(index + 1); + }else{ + return entityName; + } + } + }