/* * Copyright (c) 2016 EMC Corporation * All Rights Reserved */ package controllers; import static com.emc.vipr.client.core.TasksResources.SYSTEM_TENANT; import static com.emc.vipr.client.core.util.ResourceUtils.uri; import static controllers.Common.flashException; import static util.BourneUtil.getViprClient; import java.net.URI; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; import org.apache.commons.lang.StringUtils; import com.emc.storageos.db.client.model.ActionableEvent; import com.emc.storageos.model.TaskResourceRep; import com.emc.storageos.model.event.EventDetailsRestRep; import com.emc.storageos.model.event.EventRestRep; import com.emc.storageos.model.event.EventStatsRestRep; import com.emc.vipr.client.ViPRCoreClient; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import controllers.security.Security; import controllers.tenant.TenantSelector; import controllers.util.Models; import models.datatable.EventsDataTable; import play.data.binding.As; import play.mvc.Controller; import play.mvc.Util; import play.mvc.With; import util.EventUtils; import util.MessagesUtils; import util.StringOption; import util.TenantUtils; import util.datatable.DataTablesSupport; /** * The UI controller for actionable events * */ @With(Common.class) public class Events extends Controller { private static final String UNKNOWN = "resources.event.unknown"; private static final String APPROVED = "resources.event.approved"; private static final String APPROVED_MULTIPLE = "resources.event.approved.multiple"; private static final String DECLINED = "resources.event.declined"; private static final String DECLINED_MULTIPLE = "resources.event.declined.multiple"; private static final String APPROVE_CONFIRM_FAILED = "resources.events.approve.confirm.failed"; private static final String DECLINE_CONFIRM_FAILED = "resources.events.decline.confirm.failed"; private static final String CONFIRM_TEXT = "confirm"; private static Comparator orderedEventComparator = new Comparator<EventRestRep>() { @Override public int compare(EventRestRep o1, EventRestRep o2) { if (o1.getCreationTime() == null || o2.getCreationTime() == null) { return 1; } return o2.getCreationTime().compareTo(o1.getCreationTime()); } }; public static void listAll() { TenantSelector.addRenderArgs(); renderArgs.put("dataTable", new EventsDataTable(true)); Common.angularRenderArgs().put("tenantId", Models.currentAdminTenant()); render(); } public static void listAllJson(Long lastUpdated) { ViPRCoreClient client = getViprClient(); List<EventRestRep> eventResourceReps = client.events().getByRefs(client.events().listByTenant(uri(Models.currentAdminTenant()))); Collections.sort(eventResourceReps, orderedEventComparator); List<EventsDataTable.Event> events = Lists.newArrayList(); if (eventResourceReps != null) { for (EventRestRep eventRestRep : eventResourceReps) { EventsDataTable.Event event = new EventsDataTable.Event(eventRestRep); events.add(event); } } renderJSON(DataTablesSupport.createJSON(events, params)); } public static void getPendingAndFailedCount() { ViPRCoreClient client = getViprClient(); int activeCount = 0; Set<URI> tenants = getAccessibleTenants(); for (URI tenant : tenants) { EventStatsRestRep eventStats = client.events().getStatsByTenant(tenant); if (eventStats != null) { activeCount += eventStats.getPending() + eventStats.getFailed(); } } if (Security.isSystemAdmin()) { EventStatsRestRep systemEventStats = client.events().getStatsByTenant(SYSTEM_TENANT); if (systemEventStats != null) { activeCount += systemEventStats.getPending() + systemEventStats.getFailed(); } } renderJSON(activeCount); } /** * Returns the tenants that the logged in user has access to * * @return list of tenants */ private static Set<URI> getAccessibleTenants() { List<StringOption> tenants = Lists.newArrayList(); if (Security.isSecurityAdmin()) { tenants = TenantUtils.getSubTenantOptions(); } else if (Security.isTenantAdmin()) { tenants = TenantUtils.getUserSubTenantOptions(); } Set<URI> results = Sets.newHashSet(); for (StringOption tenant : tenants) { results.add(URI.create(tenant.id)); } results.add(TenantUtils.getUserTenant().getId()); return results; } public static void getCountSummary(URI tenantId) { ViPRCoreClient client = getViprClient(); EventStatsRestRep stats = client.events().getStatsByTenant(tenantId); renderJSON(stats); } public static void itemsJson(@As(",") String[] ids) { List<EventsDataTable.Event> results = Lists.newArrayList(); if (ids != null && ids.length > 0) { for (String id : ids) { if (StringUtils.isNotBlank(id)) { EventRestRep event = EventUtils.getEvent(uri(id)); if (event != null) { results.add(new EventsDataTable.Event(event)); } } } } renderJSON(results); } public static void details(String eventId) { if (StringUtils.isBlank(eventId)) { listAll(); } EventRestRep event = EventUtils.getEvent(uri(eventId)); if (event == null) { flash.error(MessagesUtils.get(UNKNOWN, eventId)); listAll(); } Common.angularRenderArgs().put("event", getEventSummary(event)); List<String> approveDetails = Lists.newArrayList(); List<String> declineDetails = Lists.newArrayList(); if (event.getEventStatus().equalsIgnoreCase(ActionableEvent.Status.pending.name().toString()) || event.getEventStatus().equalsIgnoreCase(ActionableEvent.Status.failed.name().toString())) { EventDetailsRestRep details = getViprClient().events().getDetails(uri(eventId)); approveDetails = details.getApproveDetails(); declineDetails = details.getDeclineDetails(); } else { approveDetails = event.getApproveDetails(); declineDetails = event.getDeclineDetails(); } Common.angularRenderArgs().put("approveDetails", approveDetails); Common.angularRenderArgs().put("declineDetails", declineDetails); List<TaskResourceRep> tasks = Lists.newArrayList(); if (event != null && event.getTaskIds() != null) { tasks = getViprClient().tasks().getByRefs(event.getTaskIds()); } render(event, approveDetails, declineDetails, tasks); } public static void detailsJson(String eventId) { if (StringUtils.isBlank(eventId)) { notFound("Event [" + eventId + "]"); } EventRestRep event = EventUtils.getEvent(uri(eventId)); if (event == null) { notFound("Event [" + eventId + "]"); } renderJSON(getEventSummary(event)); } @Util public static EventSummary getEventSummary(EventRestRep event) { EventSummary eventSummary = new EventSummary(event); return eventSummary; } private static List<EventSummary> toEventSummaries(List<EventRestRep> events) { List<EventSummary> eventSummaries = Lists.newArrayList(); for (EventRestRep event : events) { EventSummary eventSummary = new EventSummary(event); eventSummaries.add(eventSummary); } return eventSummaries; } public static void approveEvents(@As(",") String[] ids, String confirm) { try { if (!StringUtils.equalsIgnoreCase(confirm, CONFIRM_TEXT)) { throw new Exception(MessagesUtils.get(APPROVE_CONFIRM_FAILED, confirm)); } for (String eventId : ids) { getViprClient().events().approve(uri(eventId)); } flash.success(MessagesUtils.get(APPROVED_MULTIPLE)); } catch (Exception e) { flashException(e); listAll(); } listAll(); } public static void declineEvents(@As(",") String[] ids, String confirm) { try { if (!StringUtils.equalsIgnoreCase(confirm, CONFIRM_TEXT)) { throw new Exception(MessagesUtils.get(DECLINE_CONFIRM_FAILED, confirm)); } for (String eventId : ids) { getViprClient().events().decline(uri(eventId)); } flash.success(MessagesUtils.get(DECLINED_MULTIPLE)); } catch (Exception e) { flashException(e); listAll(); } listAll(); } public static void approveEvent(String eventId) { try { if (StringUtils.isNotBlank(eventId)) { getViprClient().events().approve(uri(eventId)); flash.success(MessagesUtils.get(APPROVED, eventId)); } } catch (Exception e) { flashException(e); details(eventId); } details(eventId); } public static void declineEvent(String eventId) { try { if (StringUtils.isNotBlank(eventId)) { getViprClient().events().decline(uri(eventId)); flash.success(MessagesUtils.get(DECLINED, eventId)); } } catch (Exception e) { flashException(e); details(eventId); } details(eventId); } public static void itemDetails(String id) { EventRestRep event = getViprClient().events().get(uri(id)); List<String> approveDetails = Lists.newArrayList(); List<String> declineDetails = Lists.newArrayList(); if (event.getEventStatus().equalsIgnoreCase(ActionableEvent.Status.pending.name().toString()) || event.getEventStatus().equalsIgnoreCase(ActionableEvent.Status.failed.name().toString())) { EventDetailsRestRep details = getViprClient().events().getDetails(uri(id)); approveDetails = details.getApproveDetails(); declineDetails = details.getDeclineDetails(); } else { approveDetails = event.getApproveDetails(); declineDetails = event.getDeclineDetails(); } List<TaskResourceRep> tasks = Lists.newArrayList(); if (event != null && event.getTaskIds() != null) { tasks = getViprClient().tasks().getByRefs(event.getTaskIds()); } render(approveDetails, declineDetails, event, tasks); } // "Suppressing Sonar violation of Field names should comply with naming convention" @SuppressWarnings("squid:S00116") private static class EventSummary { public URI id; public String opId; public String name; public String description; public long created; public String resourceName; public URI resourceId; public String eventStatus; public String eventCode; public String warning; public long eventExecutionTime; public List<String> approveDetails; public List<String> declineDetails; public EventSummary(EventRestRep event) { id = event.getId(); description = event.getDescription(); name = event.getName(); created = event.getCreationTime().getTimeInMillis(); resourceName = event.getResource().getName(); resourceId = event.getResource().getId(); eventStatus = event.getEventStatus(); eventCode = event.getEventCode(); warning = event.getWarning(); eventExecutionTime = event.getEventExecutionTime() == null ? 0 : event.getEventExecutionTime().getTimeInMillis(); approveDetails = event.getApproveDetails(); declineDetails = event.getDeclineDetails(); } } }