/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package controllers.resources; import static com.emc.vipr.client.core.util.ResourceUtils.uri; import static com.emc.vipr.client.core.util.ResourceUtils.uris; import static util.BourneUtil.getViprClient; import java.net.URI; import java.util.List; import java.util.Set; import org.apache.commons.lang.StringUtils; import com.emc.storageos.db.client.model.ExportGroup; import com.emc.storageos.db.client.model.ExportGroup.ExportGroupType; import com.emc.storageos.db.client.util.NullColumnValueGetter; import com.emc.storageos.model.block.export.ClustersUpdateParam; import com.emc.storageos.model.block.export.ExportGroupRestRep; import com.emc.storageos.model.block.export.ExportUpdateParam; import com.emc.storageos.model.block.export.HostsUpdateParam; import com.emc.storageos.model.block.export.InitiatorsUpdateParam; import com.emc.storageos.model.host.HostRestRep; import com.emc.storageos.model.host.InitiatorRestRep; import com.emc.storageos.model.host.cluster.ClusterRestRep; import com.emc.storageos.model.varray.VirtualArrayRestRep; import com.emc.vipr.client.Task; import com.emc.vipr.client.ViPRCoreClient; import com.emc.vipr.client.core.filters.DefaultResourceFilter; import com.emc.vipr.client.core.util.CachedResources; import com.emc.vipr.client.core.util.ResourceUtils; import com.emc.vipr.client.exceptions.ViPRHttpException; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import controllers.Common; import controllers.util.FlashException; import models.datatable.BlockExportGroupSnapshotsDataTable; import models.datatable.BlockExportGroupVolumesDataTable; import models.datatable.BlockExportGroupsDataTable; import models.datatable.HostClusterDataTable; import models.datatable.NetworkEndpointDataTable; import models.datatable.NetworkEndpointDataTable.EndpointInfo; import models.datatable.SimpleHostDataTable; import play.data.binding.As; import play.mvc.With; import util.BourneUtil; import util.ClusterUtils; import util.HostUtils; import util.MessagesUtils; import util.datatable.DataTablesSupport; @With(Common.class) public class BlockExportGroups extends ResourceController { private static final String UNKNOWN = "resources.exportgroup.unknown"; private static BlockExportGroupsDataTable blockExportGroupsDataTable = new BlockExportGroupsDataTable(); public static void exportGroups(String projectId) { setActiveProjectId(projectId); renderArgs.put("dataTable", blockExportGroupsDataTable); addReferenceData(); render(); } @FlashException(referrer = { "exportGroup" }) public static void addHosts(String exportId, @As(",") String[] ids) { ExportUpdateParam exportUpdateParam = new ExportUpdateParam(); exportUpdateParam.setHosts(new HostsUpdateParam()); if (ids != null && ids.length > 0) { for (String hostId : ids) { exportUpdateParam.getHosts().getAdd().add(uri(hostId)); } } Task<ExportGroupRestRep> task = getViprClient().blockExports().update(uri(exportId), exportUpdateParam); flash.put("info", MessagesUtils.get("resources.exportgroup.hosts.added", task.getOpId())); exportGroup(exportId); } @FlashException(referrer = { "exportGroup" }) public static void addClusters(String exportId, @As(",") String[] ids) { ExportUpdateParam exportUpdateParam = new ExportUpdateParam(); exportUpdateParam.setClusters(new ClustersUpdateParam()); if (ids != null && ids.length > 0) { for (String clusterId : ids) { exportUpdateParam.getClusters().getAdd().add(uri(clusterId)); } } Task<ExportGroupRestRep> task = getViprClient().blockExports().update(uri(exportId), exportUpdateParam); flash.put("info", MessagesUtils.get("resources.exportgroup.clusters.added", task.getOpId())); exportGroup(exportId); } @FlashException(referrer = { "exportGroup" }) public static void addInitiators(String exportId, @As(",") String[] ids) { ExportUpdateParam exportUpdateParam = new ExportUpdateParam(); exportUpdateParam.setInitiators(new InitiatorsUpdateParam()); if (ids != null && ids.length > 0) { for (String initiatorId : ids) { exportUpdateParam.getInitiators().getAdd().add(uri(initiatorId)); } } Task<ExportGroupRestRep> task = getViprClient().blockExports().update(uri(exportId), exportUpdateParam); flash.put("info", MessagesUtils.get("resources.exportgroup.initiators.added", task.getOpId())); exportGroup(exportId); } public static void exportGroupsJson(String projectId) { if (StringUtils.isNotBlank(projectId)) { setActiveProjectId(projectId); } else { projectId = getActiveProjectId(); } List<BlockExportGroupsDataTable.ExportGroup> exportGroups = BlockExportGroupsDataTable.fetch(uri(projectId)); renderJSON(DataTablesSupport.createJSON(exportGroups, params)); } /** * Return list of initiators that can be added to this export group * * @param exportGroupId id of the export group * @return list of initiators */ public static List<InitiatorRestRep> getEligibleInitiators(URI exportGroupId) { if (exportGroupId == null) { return Lists.newArrayList(); } ExportGroupRestRep exportGroup = getViprClient().blockExports().get(exportGroupId); final List<URI> initiatorsInExport = ResourceUtils.ids(exportGroup.getInitiators()); List<URI> allInitiatorIds = getViprClient().initiators().listBulkIds(); final List<URI> validHosts = getValidHostsForInitiatorExport(exportGroup); return getViprClient().initiators().getByIds(allInitiatorIds, new DefaultResourceFilter<InitiatorRestRep>() { @Override public boolean accept(InitiatorRestRep item) { return !initiatorsInExport.contains(item.getId()) && (validHosts.isEmpty() || (item.getHost() != null && !NullColumnValueGetter.isNullURI(item.getHost().getId()) && validHosts.contains(item.getHost().getId()))); } }); } /** * Returns a list of valid hosts that can be added to the provided exportGroup based on the type of export * * @param exportGroup export group * @return list of valid hosts that can be exported to this export group */ public static List<URI> getValidHostsForInitiatorExport(ExportGroupRestRep exportGroup) { if (exportGroup.getType().equals(ExportGroupType.Cluster.name()) || exportGroup.getType().equals(ExportGroupType.Host.name())) { return ResourceUtils.ids(exportGroup.getHosts()); } else if (exportGroup.getType().equals(ExportGroupType.Exclusive.name()) || exportGroup.getType().equals(ExportGroupType.Initiator.name())) { List<URI> validHosts = Lists.newArrayList(); for (InitiatorRestRep initiator : exportGroup.getInitiators()) { if (initiator.getHost() != null && !NullColumnValueGetter.isNullURI(initiator.getHost().getId())) { validHosts.add(initiator.getHost().getId()); } } return validHosts; } return Lists.newArrayList(); } public static void availableClustersJson(String exportGroupId) { List<ClusterRestRep> availableClusters = Lists.newArrayList(); ExportGroupRestRep exportGroup = getViprClient().blockExports().get(uri(exportGroupId)); List<URI> allClusterIds = getViprClient().clusters().listBulkIds(); final List<URI> exportGroupClusters = ResourceUtils.ids(exportGroup.getClusters()); availableClusters = getViprClient().clusters().getByIds(allClusterIds, new DefaultResourceFilter<ClusterRestRep>() { @Override public boolean accept(ClusterRestRep item) { return !exportGroupClusters.contains(item.getId()); } }); renderJSON(DataTablesSupport.createJSON(availableClusters, params)); } public static void availableInitiatorsJson(String id) { CachedResources<HostRestRep> hosts = HostUtils.createCache(); List<EndpointInfo> items = Lists.newArrayList(); for (InitiatorRestRep initiator : getEligibleInitiators(uri(id))) { items.add(new EndpointInfo(initiator, hosts)); } renderJSON(DataTablesSupport.createJSON(items, params)); } /** * Return list of valid hosts that can be added to the given export group * * @param exportGroup export group * @return list of hosts that can be exported */ public static List<URI> getValidHosts(ExportGroupRestRep exportGroup) { if (exportGroup.getType().equals(ExportGroup.ExportGroupType.Cluster.name())) { List<URI> hostIds = Lists.newArrayList(); for (ClusterRestRep cluster : exportGroup.getClusters()) { hostIds.addAll(ResourceUtils.ids(ClusterUtils.getHosts(cluster.getId()))); } return hostIds; } else if (exportGroup.getType().equals(ExportGroup.ExportGroupType.Host.name())) { return getViprClient().hosts().listBulkIds(); } return Lists.newArrayList(); } public static void availableHostsJson(String exportGroupId) { List<HostRestRep> availableHosts = Lists.newArrayList(); ExportGroupRestRep exportGroup = getViprClient().blockExports().get(uri(exportGroupId)); final List<URI> exportGroupHosts = ResourceUtils.ids(exportGroup.getHosts()); List<URI> hostIds = getValidHosts(exportGroup); if (!hostIds.isEmpty()) { availableHosts = getViprClient().hosts().getByIds(hostIds, new DefaultResourceFilter<HostRestRep>() { @Override public boolean accept(HostRestRep item) { return !exportGroupHosts.contains(item.getId()); } }); } renderJSON(DataTablesSupport.createJSON(availableHosts, params)); } public static void exportGroup(String exportGroupId) { ViPRCoreClient client = BourneUtil.getViprClient(); ExportGroupRestRep exportGroup = null; try { exportGroup = client.blockExports().get(uri(exportGroupId)); } catch (ViPRHttpException e) { if (e.getHttpCode() == 404) { flash.error(MessagesUtils.get(UNKNOWN, exportGroupId)); exportGroups(null); } throw e; } VirtualArrayRestRep virtualArray = null; if (exportGroup != null) { virtualArray = client.varrays().get(exportGroup.getVirtualArray()); } else { notFound("Export Group " + exportGroupId); } renderArgs.put("volumeDataTable", new BlockExportGroupVolumesDataTable()); renderArgs.put("snapshotDataTable", new BlockExportGroupSnapshotsDataTable()); SimpleHostDataTable hostsDataTable = new SimpleHostDataTable(); NetworkEndpointDataTable initiatorsDataTable = NetworkEndpointDataTable.createDataTable("FC"); initiatorsDataTable.alterColumn("portGroup").hidden().setSearchable(false); initiatorsDataTable.alterColumn("storageSystem").hidden().setSearchable(false); initiatorsDataTable.alterColumn("discovered").hidden().setSearchable(false); HostClusterDataTable clustersDataTable = new HostClusterDataTable(); render(hostsDataTable, initiatorsDataTable, clustersDataTable, exportGroup, virtualArray); } public static void exportGroupVolumesJson(String exportGroupId) { renderJSON(exportGroupId); } public static void blockSnapshotJson(String exportGroupId) { List<BlockExportGroupSnapshotsDataTable.ExportBlockSnapshot> blockSnapshots = BlockExportGroupSnapshotsDataTable .fetch(uri(exportGroupId)); renderJSON(DataTablesSupport.createJSON(blockSnapshots, params)); } public static void volumeJson(String exportGroupId) { List<BlockExportGroupVolumesDataTable.Volume> volumes = BlockExportGroupVolumesDataTable.fetch(uri(exportGroupId)); renderJSON(DataTablesSupport.createJSON(volumes, params)); } @FlashException(referrer = { "exportGroup" }) public static void deleteExportGroup(String exportGroupId) { if (StringUtils.isNotBlank(exportGroupId)) { ViPRCoreClient client = BourneUtil.getViprClient(); Task<ExportGroupRestRep> task = client.blockExports().deactivate(uri(exportGroupId)); flash.put("info", MessagesUtils.get("resources.exportgroup.deactivate")); } exportGroup(exportGroupId); } @FlashException(value = "exportGroups") public static void delete(@As(",") String[] ids) { delete(uris(ids)); } private static void delete(List<URI> ids) { if (ids != null) { ViPRCoreClient client = BourneUtil.getViprClient(); List<Task<ExportGroupRestRep>> tasks = Lists.newArrayList(); for (URI id : ids) { Task<ExportGroupRestRep> task = client.blockExports().deactivate(id); tasks.add(task); } flash.put("info", MessagesUtils.get("resources.exportgroups.deactivate", tasks.size())); } exportGroups(null); } @FlashException(referrer = { "exportGroup" }) public static void removeHost(String exportGroupId, String hostId) { ViPRCoreClient client = BourneUtil.getViprClient(); ExportUpdateParam exportUpdateParam = new ExportUpdateParam(); exportUpdateParam.setHosts(new HostsUpdateParam()); exportUpdateParam.getHosts().getRemove().add(uri(hostId)); Task<ExportGroupRestRep> task = client.blockExports().update(uri(exportGroupId), exportUpdateParam); flash.put("info", MessagesUtils.get("resources.exportgroup.host.removed", task.getOpId())); exportGroup(exportGroupId); } @FlashException(referrer = { "exportGroup" }) public static void removeCluster(String exportGroupId, String clusterId) { ViPRCoreClient client = BourneUtil.getViprClient(); ExportUpdateParam exportUpdateParam = new ExportUpdateParam(); exportUpdateParam.setClusters(new ClustersUpdateParam()); exportUpdateParam.getClusters().getRemove().add(uri(clusterId)); Task<ExportGroupRestRep> task = client.blockExports().update(uri(exportGroupId), exportUpdateParam); flash.put("info", MessagesUtils.get("resources.exportgroup.cluster.removed", task.getOpId())); exportGroup(exportGroupId); } @FlashException(referrer = { "exportGroup" }) public static void removeInitiator(String exportGroupId, String initiatorId) { ViPRCoreClient client = BourneUtil.getViprClient(); ExportUpdateParam exportUpdateParam = new ExportUpdateParam(); exportUpdateParam.setInitiators(new InitiatorsUpdateParam()); Set<URI> remove = Sets.newHashSet(); remove.add(uri(initiatorId)); exportUpdateParam.getInitiators().setRemove(remove); Task<ExportGroupRestRep> task = client.blockExports().update(uri(exportGroupId), exportUpdateParam); flash.put("info", MessagesUtils.get("resources.exportgroup.initiator.removed", task.getOpId())); exportGroup(exportGroupId); } @FlashException(referrer = { "exportGroup" }) public static void removeVolume(String exportGroupId, String volumeId) { ViPRCoreClient client = BourneUtil.getViprClient(); ExportUpdateParam exportUpdateParam = new ExportUpdateParam(); exportUpdateParam.removeVolume(uri(volumeId)); Task<ExportGroupRestRep> task = client.blockExports().update(uri(exportGroupId), exportUpdateParam); flash.put("info", MessagesUtils.get("resources.exportgroup.volume.removed", task.getOpId())); exportGroup(exportGroupId); } @FlashException(referrer = { "exportGroup" }) public static void removeSnapshot(String exportGroupId, String snapshotId) { ViPRCoreClient client = BourneUtil.getViprClient(); ExportUpdateParam exportUpdateParam = new ExportUpdateParam(); exportUpdateParam.removeVolume(uri(snapshotId)); Task<ExportGroupRestRep> task = client.blockExports().update(uri(exportGroupId), exportUpdateParam); flash.put("info", MessagesUtils.get("resources.exportgroup.snapshot.removed", task.getOpId())); exportGroup(exportGroupId); } }