You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2014/03/06 23:07:13 UTC

[30/50] [abbrv] git commit: updated refs/heads/rbac to 48e08fe

CLOUDSTACK-6199: Action Events - hide them when display flag is off in the context of "Ability to have better control over first class objects in CS" feature.
For root admin - s/he should be able to see all the events despite the value of the flag.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/339c4f4c
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/339c4f4c
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/339c4f4c

Branch: refs/heads/rbac
Commit: 339c4f4c3fb4f50e58b780893b16be192f985d82
Parents: 45fa91c
Author: Nitin Mehta <ni...@citrix.com>
Authored: Tue Mar 4 14:59:30 2014 -0800
Committer: Nitin Mehta <ni...@citrix.com>
Committed: Tue Mar 4 14:59:30 2014 -0800

----------------------------------------------------------------------
 api/src/com/cloud/server/ManagementService.java |  4 +-
 api/src/com/cloud/storage/Volume.java           |  2 +
 api/src/com/cloud/uservm/UserVm.java            |  1 +
 .../org/apache/cloudstack/api/BaseAsyncCmd.java |  6 ++-
 api/src/org/apache/cloudstack/api/BaseCmd.java  |  8 ++++
 .../api/command/user/vm/UpdateVMCmd.java        | 10 +++++
 .../command/user/volume/AttachVolumeCmd.java    |  9 ++++
 .../command/user/volume/CreateVolumeCmd.java    | 10 +++++
 .../apache/cloudstack/context/CallContext.java  | 13 ++++++
 engine/schema/src/com/cloud/event/EventVO.java  | 11 +++++
 .../schema/src/com/cloud/storage/VolumeVO.java  |  1 +
 .../cloudstack/storage/volume/VolumeObject.java |  5 +++
 server/src/com/cloud/api/ApiDispatcher.java     |  3 +-
 server/src/com/cloud/api/ApiServer.java         |  3 +-
 .../com/cloud/api/query/QueryManagerImpl.java   |  7 ++++
 .../src/com/cloud/api/query/vo/EventJoinVO.java |  7 ++++
 .../com/cloud/event/ActionEventInterceptor.java | 19 +++++----
 .../src/com/cloud/event/ActionEventUtils.java   | 34 +++++++++------
 .../com/cloud/server/ManagementServerImpl.java  |  8 ++--
 .../storage/snapshot/SnapshotSchedulerImpl.java |  2 +-
 setup/db/db/schema-430to440.sql                 | 44 ++++++++++++++++++++
 21 files changed, 176 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/api/src/com/cloud/server/ManagementService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java
index 24fad87..9b138fe 100755
--- a/api/src/com/cloud/server/ManagementService.java
+++ b/api/src/com/cloud/server/ManagementService.java
@@ -269,9 +269,9 @@ public interface ManagementService {
      */
     String generateRandomPassword();
 
-    public Long saveStartedEvent(Long userId, Long accountId, String type, String description, long startEventId);
+    public Long saveStartedEvent(Long userId, Long accountId, String type, String description, boolean startEventId, Long displayResourceEnabled);
 
-    public Long saveCompletedEvent(Long userId, Long accountId, String level, String type, String description, long startEventId);
+    public Long saveCompletedEvent(Long userId, Long accountId, String level, String type, String description, boolean displayResourceEnabled, long startEventId);
 
     /**
      * Search registered key pairs for the logged in user.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/api/src/com/cloud/storage/Volume.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java
index 3664884..304dbcf 100755
--- a/api/src/com/cloud/storage/Volume.java
+++ b/api/src/com/cloud/storage/Volume.java
@@ -190,4 +190,6 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
     Long getVmSnapshotChainSize();
 
     Integer getHypervisorSnapshotReserve();
+
+    boolean isDisplayVolume();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/api/src/com/cloud/uservm/UserVm.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/uservm/UserVm.java b/api/src/com/cloud/uservm/UserVm.java
index b1d1712..16a2037 100755
--- a/api/src/com/cloud/uservm/UserVm.java
+++ b/api/src/com/cloud/uservm/UserVm.java
@@ -39,4 +39,5 @@ public interface UserVm extends VirtualMachine, ControlledEntity {
 
     void setAccountId(long accountId);
 
+    public boolean isDisplayVm();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java b/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java
index ae0f5d7..bbc898f 100644
--- a/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseAsyncCmd.java
@@ -105,7 +105,8 @@ public abstract class BaseAsyncCmd extends BaseCmd {
         if (startEvent == null) {
             startEvent = 0L;
         }
-        return _mgr.saveStartedEvent((userId == null) ? User.UID_SYSTEM : userId, getEntityOwnerId(), eventType, description, startEvent);
+        return _mgr.saveStartedEvent((userId == null) ? User.UID_SYSTEM : userId, getEntityOwnerId(), eventType, description,
+                isDisplayResourceEnabled(), startEvent);
     }
 
     protected long saveCompletedEvent(String level, String description) {
@@ -120,7 +121,8 @@ public abstract class BaseAsyncCmd extends BaseCmd {
         if (startEvent == null) {
             startEvent = 0L;
         }
-        return _mgr.saveCompletedEvent((userId == null) ? User.UID_SYSTEM : userId, getEntityOwnerId(), level, eventType, description, startEvent);
+        return _mgr.saveCompletedEvent((userId == null) ? User.UID_SYSTEM : userId, getEntityOwnerId(), level, eventType, description,
+                isDisplayResourceEnabled(), startEvent);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/api/src/org/apache/cloudstack/api/BaseCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java
index 0e83cee..e869ddf 100644
--- a/api/src/org/apache/cloudstack/api/BaseCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseCmd.java
@@ -411,4 +411,12 @@ public abstract class BaseCmd {
         }
         return null;
     }
+
+    /**
+     * display flag is used to control the display of the resource only to the end user. It doesnt affect Root Admin.
+     * @return display flag
+     */
+    public boolean isDisplayResourceEnabled(){
+        return true;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
index 9e16f01..eb3b955 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/UpdateVMCmd.java
@@ -144,6 +144,16 @@ public class UpdateVMCmd extends BaseCustomIdCmd {
     }
 
     @Override
+    public boolean isDisplayResourceEnabled(){
+        UserVm userVm = _entityMgr.findById(UserVm.class, getId());
+        if (userVm != null) {
+            return userVm.isDisplayVm();
+        }
+
+        return true; // no info means true
+    }
+
+    @Override
     public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException {
         CallContext.current().setEventDetails("Vm Id: " + getId());
         UserVm result = _userVmService.updateVirtualMachine(this);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java
index 714d7cb..78e1a69 100644
--- a/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/volume/AttachVolumeCmd.java
@@ -108,6 +108,15 @@ public class AttachVolumeCmd extends BaseAsyncCmd {
     }
 
     @Override
+    public boolean isDisplayResourceEnabled(){
+        Volume volume = _responseGenerator.findVolumeById(getId());
+        if (volume == null) {
+            return true; // bad id given, parent this command to true so ERROR events are tracked
+        }
+        return volume.isDisplayVolume();
+    }
+
+    @Override
     public String getEventDescription() {
         return "attaching volume: " + getId() + " to vm: " + getVirtualMachineId();
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java
index ee0ab0c..555711b 100644
--- a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java
@@ -152,6 +152,10 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd {
     }
 
     public Boolean getDisplayVolume() {
+        if(displayVolume == null){
+            return true;
+        }
+
         return displayVolume;
     }
 
@@ -192,6 +196,11 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd {
     }
 
     @Override
+    public boolean isDisplayResourceEnabled(){
+        return getDisplayVolume();
+    }
+
+    @Override
     public String getEventDescription() {
         return "creating volume: " + getVolumeName() + ((getSnapshotId() == null) ? "" : " from snapshot: " + getSnapshotId());
     }
@@ -211,6 +220,7 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd {
     @Override
     public void execute() {
         CallContext.current().setEventDetails("Volume Id: " + getEntityId() + ((getSnapshotId() == null) ? "" : " from snapshot: " + getSnapshotId()));
+        CallContext.current().setEventDisplayEnabled(getDisplayVolume());
         Volume volume = _volumeService.createVolume(this);
         if (volume != null) {
             VolumeResponse response = _responseGenerator.createVolumeResponse(volume);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/api/src/org/apache/cloudstack/context/CallContext.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/context/CallContext.java b/api/src/org/apache/cloudstack/context/CallContext.java
index 22ea55f..661b01d 100644
--- a/api/src/org/apache/cloudstack/context/CallContext.java
+++ b/api/src/org/apache/cloudstack/context/CallContext.java
@@ -55,6 +55,7 @@ public class CallContext {
     private String eventDescription;
     private String eventDetails;
     private String eventType;
+    private boolean isEventDisplayEnabled = true; // default to true unless specifically set
     private User user;
     private long userId;
     private final Map<Object, Object> context = new HashMap<Object, Object>();
@@ -303,6 +304,18 @@ public class CallContext {
         this.eventDescription = eventDescription;
     }
 
+    /**
+     * Whether to display the event to the end user.
+     * @return true - if the event is to be displayed to the end user, false otherwise.
+     */
+    public boolean isEventDisplayEnabled() {
+        return isEventDisplayEnabled;
+    }
+
+    public void setEventDisplayEnabled(boolean eventDisplayEnabled) {
+        isEventDisplayEnabled = eventDisplayEnabled;
+    }
+
     public static void setActionEventInfo(String eventType, String description) {
         CallContext context = CallContext.current();
         if (context != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/engine/schema/src/com/cloud/event/EventVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/event/EventVO.java b/engine/schema/src/com/cloud/event/EventVO.java
index 487ba84..91174fc 100644
--- a/engine/schema/src/com/cloud/event/EventVO.java
+++ b/engine/schema/src/com/cloud/event/EventVO.java
@@ -76,6 +76,9 @@ public class EventVO implements Event {
     @Column(name = "archived")
     private boolean archived;
 
+    @Column(name = "display_event", updatable = true, nullable = false)
+    protected boolean isDisplayEventEnabled = true;
+
     @Transient
     private int totalSize;
 
@@ -208,4 +211,12 @@ public class EventVO implements Event {
     public void setArchived(Boolean archived) {
         this.archived = archived;
     }
+
+    public boolean isDisplayEventEnabled() {
+        return isDisplayEventEnabled;
+    }
+
+    public void setDisplayEventEnabled(boolean displayEventEnabled) {
+        isDisplayEventEnabled = displayEventEnabled;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/engine/schema/src/com/cloud/storage/VolumeVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/VolumeVO.java b/engine/schema/src/com/cloud/storage/VolumeVO.java
index 901e07c..fb79c13 100755
--- a/engine/schema/src/com/cloud/storage/VolumeVO.java
+++ b/engine/schema/src/com/cloud/storage/VolumeVO.java
@@ -547,6 +547,7 @@ public class VolumeVO implements Volume {
         this._iScsiName = iScsiName;
     }
 
+    @Override
     public boolean isDisplayVolume() {
         return displayVolume;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
----------------------------------------------------------------------
diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
index fd0f2c1..1653dcb 100644
--- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
+++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java
@@ -162,6 +162,11 @@ public class VolumeObject implements VolumeInfo {
         return volumeVO.getHypervisorSnapshotReserve();
     }
 
+    @Override
+    public boolean isDisplayVolume() {
+        return volumeVO.isDisplayVolume();
+    }
+
     public long getVolumeId() {
         return volumeVO.getId();
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/server/src/com/cloud/api/ApiDispatcher.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java
index ed95c72..5bdefe7 100755
--- a/server/src/com/cloud/api/ApiDispatcher.java
+++ b/server/src/com/cloud/api/ApiDispatcher.java
@@ -101,7 +101,7 @@ public class ApiDispatcher {
 
     public void dispatchCreateCmd(BaseAsyncCreateCmd cmd, Map<String, String> params) throws Exception {
         processParameters(cmd, params);
-
+        CallContext.current().setEventDisplayEnabled(cmd.isDisplayResourceEnabled());
         cmd.create();
 
     }
@@ -131,6 +131,7 @@ public class ApiDispatcher {
     public void dispatch(BaseCmd cmd, Map<String, String> params, boolean execute) throws Exception {
         processParameters(cmd, params);
         CallContext ctx = CallContext.current();
+        ctx.setEventDisplayEnabled(cmd.isDisplayResourceEnabled());
 
         if (cmd instanceof BaseAsyncCmd) {
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index 25792fb..3df599e 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -479,6 +479,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
         CallContext ctx = CallContext.current();
         Long callerUserId = ctx.getCallingUserId();
         Account caller = ctx.getCallingAccount();
+        ctx.setEventDisplayEnabled(cmdObj.isDisplayResourceEnabled());
 
         // Queue command based on Cmd super class:
         // BaseCmd: cmd is dispatched to ApiDispatcher, executed, serialized and returned.
@@ -512,7 +513,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
             // save the scheduled event
             Long eventId =
                 ActionEventUtils.onScheduledActionEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(),
-                    asyncCmd.getEventDescription(), startEventId);
+                    asyncCmd.getEventDescription(), asyncCmd.isDisplayResourceEnabled(), startEventId);
             if (startEventId == 0) {
                 // There was no create event before, set current event id as start eventId
                 startEventId = eventId;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/server/src/com/cloud/api/query/QueryManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java
index 69c25ee..66794c0 100644
--- a/server/src/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
@@ -504,9 +504,16 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
         sb.and("state", sb.entity().getState(), SearchCriteria.Op.NEQ);
         sb.and("startId", sb.entity().getStartId(), SearchCriteria.Op.EQ);
         sb.and("createDate", sb.entity().getCreateDate(), SearchCriteria.Op.BETWEEN);
+        sb.and("displayEvent", sb.entity().getDisplayEvent(), SearchCriteria.Op.EQ);
         sb.and("archived", sb.entity().getArchived(), SearchCriteria.Op.EQ);
 
         SearchCriteria<EventJoinVO> sc = sb.create();
+
+        // For end users display only enabled events
+        if(!_accountMgr.isRootAdmin(caller.getType())){
+            sc.setParameters("displayEvent", true);
+        }
+
         // building ACL condition
         _accountMgr.buildACLViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/server/src/com/cloud/api/query/vo/EventJoinVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/vo/EventJoinVO.java b/server/src/com/cloud/api/query/vo/EventJoinVO.java
index 5950e70..6571269 100644
--- a/server/src/com/cloud/api/query/vo/EventJoinVO.java
+++ b/server/src/com/cloud/api/query/vo/EventJoinVO.java
@@ -106,6 +106,9 @@ public class EventJoinVO extends BaseViewVO implements ControlledViewEntity {
     @Column(name = "archived")
     private boolean archived;
 
+    @Column(name = "display_event")
+    protected boolean displayEvent = true;
+
     public EventJoinVO() {
     }
 
@@ -216,4 +219,8 @@ public class EventJoinVO extends BaseViewVO implements ControlledViewEntity {
     public boolean getArchived() {
         return archived;
     }
+
+    public boolean getDisplayEvent() {
+        return displayEvent;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/server/src/com/cloud/event/ActionEventInterceptor.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/event/ActionEventInterceptor.java b/server/src/com/cloud/event/ActionEventInterceptor.java
index 275c2d0..df8010c 100644
--- a/server/src/com/cloud/event/ActionEventInterceptor.java
+++ b/server/src/com/cloud/event/ActionEventInterceptor.java
@@ -71,8 +71,9 @@ public class ActionEventInterceptor implements ComponentMethodInterceptor, Metho
 
                 String eventDescription = getEventDescription(actionEvent, ctx);
                 String eventType = getEventType(actionEvent, ctx);
+                boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled();
 
-                ActionEventUtils.onStartedActionEventFromContext(eventType, eventDescription);
+                ActionEventUtils.onStartedActionEventFromContext(eventType, eventDescription, isEventDisplayEnabled);
             }
         }
         return event;
@@ -87,17 +88,19 @@ public class ActionEventInterceptor implements ComponentMethodInterceptor, Metho
             long startEventId = ctx.getStartEventId();
             String eventDescription = getEventDescription(actionEvent, ctx);
             String eventType = getEventType(actionEvent, ctx);
+            boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled();
 
             if (eventType.equals(""))
                 return;
 
             if (actionEvent.create()) {
                 //This start event has to be used for subsequent events of this action
-                startEventId =
-                    ActionEventUtils.onCreatedActionEvent(userId, accountId, EventVO.LEVEL_INFO, eventType, "Successfully created entity for " + eventDescription);
+                startEventId = ActionEventUtils.onCreatedActionEvent(userId, accountId, EventVO.LEVEL_INFO, eventType,
+                        isEventDisplayEnabled, "Successfully created entity for " + eventDescription);
                 ctx.setStartEventId(startEventId);
             } else {
-                ActionEventUtils.onCompletedActionEvent(userId, accountId, EventVO.LEVEL_INFO, eventType, "Successfully completed " + eventDescription, startEventId);
+                ActionEventUtils.onCompletedActionEvent(userId, accountId, EventVO.LEVEL_INFO, eventType,
+                        isEventDisplayEnabled, "Successfully completed " + eventDescription, startEventId);
             }
         }
     }
@@ -111,16 +114,18 @@ public class ActionEventInterceptor implements ComponentMethodInterceptor, Metho
             long startEventId = ctx.getStartEventId();
             String eventDescription = getEventDescription(actionEvent, ctx);
             String eventType = getEventType(actionEvent, ctx);
+            boolean isEventDisplayEnabled = ctx.isEventDisplayEnabled();
 
             if (eventType.equals(""))
                 return;
 
             if (actionEvent.create()) {
-                long eventId =
-                    ActionEventUtils.onCreatedActionEvent(userId, accountId, EventVO.LEVEL_ERROR, eventType, "Error while creating entity for " + eventDescription);
+                long eventId = ActionEventUtils.onCreatedActionEvent(userId, accountId, EventVO.LEVEL_ERROR, eventType,
+                            isEventDisplayEnabled, "Error while creating entity for " + eventDescription);
                 ctx.setStartEventId(eventId);
             } else {
-                ActionEventUtils.onCompletedActionEvent(userId, accountId, EventVO.LEVEL_ERROR, eventType, "Error while " + eventDescription, startEventId);
+                ActionEventUtils.onCompletedActionEvent(userId, accountId, EventVO.LEVEL_ERROR, eventType, isEventDisplayEnabled,
+                        "Error while " + eventDescription, startEventId);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/server/src/com/cloud/event/ActionEventUtils.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/event/ActionEventUtils.java b/server/src/com/cloud/event/ActionEventUtils.java
index c332a8e..a9999dc 100755
--- a/server/src/com/cloud/event/ActionEventUtils.java
+++ b/server/src/com/cloud/event/ActionEventUtils.java
@@ -84,7 +84,7 @@ public class ActionEventUtils {
 
         publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, com.cloud.event.Event.State.Completed, description);
 
-        Event event = persistActionEvent(userId, accountId, domainId, null, type, Event.State.Completed, description, null);
+        Event event = persistActionEvent(userId, accountId, domainId, null, type, Event.State.Completed, true, description, null);
 
         return event.getId();
     }
@@ -92,67 +92,75 @@ public class ActionEventUtils {
     /*
      * Save event after scheduling an async job
      */
-    public static Long onScheduledActionEvent(Long userId, Long accountId, String type, String description, long startEventId) {
+    public static Long onScheduledActionEvent(Long userId, Long accountId, String type, String description, boolean eventDisplayEnabled, long startEventId) {
 
         publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, com.cloud.event.Event.State.Scheduled, description);
 
-        Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Scheduled, description, startEventId);
+        Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Scheduled, eventDisplayEnabled, description, startEventId);
 
         return event.getId();
     }
 
     public static void startNestedActionEvent(String eventType, String eventDescription) {
         CallContext.setActionEventInfo(eventType, eventDescription);
-        onStartedActionEventFromContext(eventType, eventDescription);
+        onStartedActionEventFromContext(eventType, eventDescription, true);
     }
 
-    public static void onStartedActionEventFromContext(String eventType, String eventDescription) {
+    public static void onStartedActionEventFromContext(String eventType, String eventDescription, boolean eventDisplayEnabled) {
         CallContext ctx = CallContext.current();
         long userId = ctx.getCallingUserId();
         long accountId = ctx.getCallingAccountId();
         long startEventId = ctx.getStartEventId();
 
         if (!eventType.equals(""))
-            ActionEventUtils.onStartedActionEvent(userId, accountId, eventType, eventDescription, startEventId);
+            ActionEventUtils.onStartedActionEvent(userId, accountId, eventType, eventDescription, eventDisplayEnabled, startEventId);
     }
 
     /*
      * Save event after starting execution of an async job
      */
-    public static Long onStartedActionEvent(Long userId, Long accountId, String type, String description, long startEventId) {
+    public static Long onStartedActionEvent(Long userId, Long accountId, String type, String description, boolean eventDisplayEnabled, long startEventId) {
 
         publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, com.cloud.event.Event.State.Started, description);
 
-        Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Started, description, startEventId);
+        Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Started, eventDisplayEnabled, description, startEventId);
+
         return event.getId();
     }
 
     public static Long onCompletedActionEvent(Long userId, Long accountId, String level, String type, String description, long startEventId) {
 
+        return onCompletedActionEvent(userId, accountId, level, type, true, description, startEventId);
+    }
+
+    public static Long onCompletedActionEvent(Long userId, Long accountId, String level, String type, boolean eventDisplayEnabled, String description, long startEventId) {
         publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, com.cloud.event.Event.State.Completed, description);
 
-        Event event = persistActionEvent(userId, accountId, null, level, type, Event.State.Completed, description, startEventId);
+        Event event = persistActionEvent(userId, accountId, null, level, type, Event.State.Completed, eventDisplayEnabled, description, startEventId);
 
         return event.getId();
+
     }
 
-    public static Long onCreatedActionEvent(Long userId, Long accountId, String level, String type, String description) {
+    public static Long onCreatedActionEvent(Long userId, Long accountId, String level, String type, boolean eventDisplayEnabled, String description) {
 
         publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type, com.cloud.event.Event.State.Created, description);
 
-        Event event = persistActionEvent(userId, accountId, null, level, type, Event.State.Created, description, null);
+        Event event = persistActionEvent(userId, accountId, null, level, type, Event.State.Created, eventDisplayEnabled, 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) {
+    private static Event persistActionEvent(Long userId, Long accountId, Long domainId, String level, String type,
+                                            Event.State state, boolean eventDisplayEnabled, String description, Long startEventId) {
         EventVO event = new EventVO();
         event.setUserId(userId);
         event.setAccountId(accountId);
         event.setType(type);
         event.setState(state);
         event.setDescription(description);
+        event.setDisplayEventEnabled(eventDisplayEnabled);
+
         if (domainId != null) {
             event.setDomainId(domainId);
         } else {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 62faafc..4fa9467 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -3301,13 +3301,13 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
     }
 
     @Override
-    public Long saveStartedEvent(Long userId, Long accountId, String type, String description, long startEventId) {
-        return ActionEventUtils.onStartedActionEvent(userId, accountId, type, description, startEventId);
+    public Long saveStartedEvent(Long userId, Long accountId, String type, String description, boolean displayResourceEnabled, Long startEventId) {
+        return ActionEventUtils.onStartedActionEvent(userId, accountId, type, description, displayResourceEnabled, startEventId);
     }
 
     @Override
-    public Long saveCompletedEvent(Long userId, Long accountId, String level, String type, String description, long startEventId) {
-        return ActionEventUtils.onCompletedActionEvent(userId, accountId, level, type, description, startEventId);
+    public Long saveCompletedEvent(Long userId, Long accountId, String level, String type, String description, boolean displayResourceEnabled, long startEventId) {
+        return ActionEventUtils.onCompletedActionEvent(userId, accountId, level, type, displayResourceEnabled, description, startEventId);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
index 183a13a..a85c052 100644
--- a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java
@@ -245,7 +245,7 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu
                 tmpSnapshotScheduleVO = _snapshotScheduleDao.acquireInLockTable(snapshotScheId);
                 Long eventId =
                     ActionEventUtils.onScheduledActionEvent(User.UID_SYSTEM, volume.getAccountId(), EventTypes.EVENT_SNAPSHOT_CREATE, "creating snapshot for volume Id:" +
-                        volumeId, 0);
+                        volumeId, true, 0);
 
                 Map<String, String> params = new HashMap<String, String>();
                 params.put(ApiConstants.VOLUME_ID, "" + volumeId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/339c4f4c/setup/db/db/schema-430to440.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql
index 0ded7a9..ec7ee4d 100644
--- a/setup/db/db/schema-430to440.sql
+++ b/setup/db/db/schema-430to440.sql
@@ -542,3 +542,47 @@ ALTER TABLE `cloud`.`s2s_vpn_gateway` ADD COLUMN `display` tinyint(1) NOT NULL D
 
 INSERT IGNORE INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (225, UUID(), 9, 'FreeBSD 10 (32-bit)');
 INSERT IGNORE INTO `cloud`.`guest_os` (id, uuid, category_id, display_name) VALUES (226, UUID(), 9, 'FreeBSD 10 (64-bit)');
+
+DROP VIEW IF EXISTS `cloud`.`event_view`;
+CREATE VIEW `cloud`.`event_view` AS
+    select
+        event.id,
+        event.uuid,
+        event.type,
+        event.state,
+        event.description,
+        event.created,
+        event.level,
+        event.parameters,
+        event.start_id,
+        eve.uuid start_uuid,
+        event.user_id,
+        event.archived,
+        event.display_event,
+        user.username user_name,
+        account.id account_id,
+        account.uuid account_uuid,
+        account.account_name account_name,
+        account.type account_type,
+        domain.id domain_id,
+        domain.uuid domain_uuid,
+        domain.name domain_name,
+        domain.path domain_path,
+        projects.id project_id,
+        projects.uuid project_uuid,
+        projects.name project_name
+    from
+        `cloud`.`event`
+            inner join
+        `cloud`.`account` ON event.account_id = account.id
+            inner join
+        `cloud`.`domain` ON event.domain_id = domain.id
+            inner join
+        `cloud`.`user` ON event.user_id = user.id
+            left join
+        `cloud`.`projects` ON projects.project_account_id = event.account_id
+            left join
+        `cloud`.`event` eve ON event.start_id = eve.id;
+
+
+