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.
This commit is contained in:
Nitin Mehta 2014-03-04 14:59:30 -08:00
parent 45fa91c490
commit 339c4f4c3f
21 changed files with 180 additions and 35 deletions

View File

@ -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.

View File

@ -190,4 +190,6 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
Long getVmSnapshotChainSize();
Integer getHypervisorSnapshotReserve();
boolean isDisplayVolume();
}

View File

@ -39,4 +39,5 @@ public interface UserVm extends VirtualMachine, ControlledEntity {
void setAccountId(long accountId);
public boolean isDisplayVm();
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -143,6 +143,16 @@ public class UpdateVMCmd extends BaseCustomIdCmd {
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
}
@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());

View File

@ -107,6 +107,15 @@ public class AttachVolumeCmd extends BaseAsyncCmd {
return EventTypes.EVENT_VOLUME_ATTACH;
}
@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();

View File

@ -152,6 +152,10 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd {
}
public Boolean getDisplayVolume() {
if(displayVolume == null){
return true;
}
return displayVolume;
}
@ -191,6 +195,11 @@ public class CreateVolumeCmd extends BaseAsyncCreateCustomIdCmd {
return EventTypes.EVENT_VOLUME_CREATE;
}
@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);

View File

@ -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) {

View File

@ -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;
}
}

View File

@ -547,6 +547,7 @@ public class VolumeVO implements Volume {
this._iScsiName = iScsiName;
}
@Override
public boolean isDisplayVolume() {
return displayVolume;
}

View File

@ -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();
}

View File

@ -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) {

View File

@ -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;

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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) {
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);
return event.getId();
return onCompletedActionEvent(userId, accountId, level, type, true, description, startEventId);
}
public static Long onCreatedActionEvent(Long userId, Long accountId, String level, String type, String description) {
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, eventDisplayEnabled, description, startEventId);
return event.getId();
}
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 {

View File

@ -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

View File

@ -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);

View File

@ -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;