/*
* Copyright (c) 2015 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.fileorchestrationcontroller;
import java.io.Serializable;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper;
public class FileDescriptor implements Serializable {
public FileDescriptor(Type type, URI deviceURI, URI fsURI, URI poolURI,
Long fileSize,
VirtualPoolCapabilityValuesWrapper capabilitiesValues,
URI migrationId, String suggestedNativeFsId) {
super();
this._type = type;
this._deviceURI = deviceURI;
this._fsURI = fsURI;
this._poolURI = poolURI;
this._fileSize = fileSize;
this._capabilitiesValues = capabilitiesValues;
this._migrationId = migrationId;
this._suggestedNativeFsId = suggestedNativeFsId;
}
public FileDescriptor(Type type, URI fsURI) {
super();
this._type = type;
this._fsURI = fsURI;
}
public FileDescriptor(Type type, URI deviceURI, URI fsURI, URI poolURI,
String deletionType, boolean forceDelete) {
super();
this._type = type;
this._deviceURI = deviceURI;
this._fsURI = fsURI;
this._poolURI = poolURI;
this.deleteType = deletionType;
this.forceDelete = forceDelete;
}
public FileDescriptor(Type type, URI deviceURI, URI fsURI, URI poolURI,
String deletionType, boolean forceDelete, Long fileSize) {
this(type, deviceURI, fsURI, poolURI, deletionType, forceDelete);
this._fileSize = fileSize;
}
public FileDescriptor(Type type, URI deviceURI, URI fsURI, URI poolURI,
String deletionType, boolean forceDelete, boolean deleteTargetOnly) {
super();
this._type = type;
this._deviceURI = deviceURI;
this._fsURI = fsURI;
this._poolURI = poolURI;
this.deleteType = deletionType;
this.forceDelete = forceDelete;
this.deleteTargetOnly = deleteTargetOnly;
}
public enum Type {
/* ******************************
* The ordering of these are important for the sortByType() method,
* be mindful when adding/removing/changing the list.
*/
FILE_DATA(1), // user's data filesystem
FILE_LOCAL_MIRROR_TARGET(2), // array level mirror
FILE_SNAPSHOT(3), // array level snapshot
FILE_EXISTING_SOURCE(4), // existing source file
FILE_MIRROR_SOURCE(5), // remote mirror source
FILE_MIRROR_TARGET(6), // remote mirror target
FILE_EXISTING_MIRROR_SOURCE(7); // change vpool of filesystem
private final int order;
private Type(int order) {
this.order = order;
}
public int getOrder() {
return order;
}
};
public enum DeleteType {
FULL,
VIPR_ONLY
}
private Type _type; // The type of this file
private URI _deviceURI; // Device this file will be created on
private URI _fsURI; // The file id or FileObject or FileShare id to be created
private URI _poolURI; // The pool id to be used for creation
private Long _fileSize; // Used to separate multi-file create requests
private VirtualPoolCapabilityValuesWrapper _capabilitiesValues; // mirror policy is stored in here
private URI _migrationId; // Reference to the migration object for this file
private String _suggestedNativeFsId; // user suggested native id
private String deleteType; // delete type either FULL or VIPR_ONLY
private boolean deleteTargetOnly;
public String getDeleteType() {
return deleteType;
}
public void setDeleteType(String deleteType) {
this.deleteType = deleteType;
}
public boolean isForceDelete() {
return forceDelete;
}
public void setForceDelete(boolean forceDelete) {
this.forceDelete = forceDelete;
}
private boolean forceDelete;
public String getSuggestedNativeFsId() {
return _suggestedNativeFsId;
}
public void setSuggestedNativeFsId(String suggestedNativeFsId) {
this._suggestedNativeFsId = suggestedNativeFsId;
}
public Type getType() {
return _type;
}
public void setType(Type type) {
this._type = type;
}
public URI getDeviceURI() {
return _deviceURI;
}
public void setDeviceURI(URI deviceURI) {
this._deviceURI = deviceURI;
}
public URI getFsURI() {
return _fsURI;
}
public void setFsURI(URI fsURI) {
this._fsURI = fsURI;
}
public URI getPoolURI() {
return _poolURI;
}
public void setPoolURI(URI poolURI) {
this._poolURI = poolURI;
}
public VirtualPoolCapabilityValuesWrapper getCapabilitiesValues() {
return _capabilitiesValues;
}
public void setCapabilitiesValues(VirtualPoolCapabilityValuesWrapper capabilitiesValues) {
this._capabilitiesValues = capabilitiesValues;
}
public Long getFileSize() {
return _fileSize;
}
public void setFileSize(Long fileSize) {
this._fileSize = fileSize;
}
public URI getMigrationId() {
return _migrationId;
}
public void setMigrationId(URI migrationId) {
this._migrationId = migrationId;
}
public boolean isDeleteTargetOnly() {
return deleteTargetOnly;
}
public void setDeleteTargetOnly(boolean deleteTargetOnly) {
this.deleteTargetOnly = deleteTargetOnly;
}
/**
* Sorts the descriptors using the natural order of the enum type
* defined at the top of the class.
*
* @param descriptors FileDescriptors to sort
*/
public static void sortByType(List<FileDescriptor> descriptors) {
Collections.sort(descriptors, new Comparator<FileDescriptor>() {
@Override
public int compare(FileDescriptor vd1, FileDescriptor vd2) {
return vd1.getType().getOrder() - vd2.getType().getOrder();
}
});
}
/**
* Return a map of device URI to a list of descriptors in that device.
*
* @param descriptors List<FileDescriptors>
* @return Map of device URI to List<FileDescriptors> in that device
*/
static public Map<URI, List<FileDescriptor>> getDeviceMap(List<FileDescriptor> descriptors) {
HashMap<URI, List<FileDescriptor>> poolMap = new HashMap<URI, List<FileDescriptor>>();
for (FileDescriptor desc : descriptors) {
if (poolMap.get(desc._deviceURI) == null) {
poolMap.put(desc._deviceURI, new ArrayList<FileDescriptor>());
}
poolMap.get(desc._deviceURI).add(desc);
}
return poolMap;
}
/**
* Return a map of pool URI to a list of descriptors in that pool.
*
* @param descriptors List<FileDescriptors>
* @return Map of pool URI to List<FileDescriptors> in that pool
*/
static public Map<URI, List<FileDescriptor>> getPoolMap(List<FileDescriptor> descriptors) {
HashMap<URI, List<FileDescriptor>> poolMap = new HashMap<URI, List<FileDescriptor>>();
for (FileDescriptor desc : descriptors) {
if (poolMap.get(desc._poolURI) == null) {
poolMap.put(desc._poolURI, new ArrayList<FileDescriptor>());
}
poolMap.get(desc._poolURI).add(desc);
}
return poolMap;
}
/**
* Returns all the descriptors of a given type.
*
* @param descriptors List<FileDescriptor> input list
* @param type enum Type
* @return returns list elements matching given type
*/
static public List<FileDescriptor> getDescriptors(List<FileDescriptor> descriptors, Type type) {
List<FileDescriptor> list = new ArrayList<FileDescriptor>();
for (FileDescriptor descriptor : descriptors) {
if (descriptor._type == type) {
list.add(descriptor);
}
}
return list;
}
/**
* Return a map of pool URI to a list of descriptors in that pool of each size.
*
* @param descriptors List<FileDescriptors>
* @return Map of pool URI to a map of identical sized filesystems to List<FileDescriptors> in that pool of that size
*/
static public Map<URI, Map<Long, List<FileDescriptor>>> getPoolSizeMap(List<FileDescriptor> descriptors) {
Map<URI, Map<Long, List<FileDescriptor>>> poolSizeMap = new HashMap<URI, Map<Long, List<FileDescriptor>>>();
for (FileDescriptor desc : descriptors) {
// If the outside pool map doesn't exist, create it.
if (poolSizeMap.get(desc._poolURI) == null) {
poolSizeMap.put(desc._poolURI, new HashMap<Long, List<FileDescriptor>>());
}
// If the inside size map doesn't exist, create it.
if (poolSizeMap.get(desc._poolURI).get(desc.getFileSize()) == null) {
poolSizeMap.get(desc._poolURI).put(desc.getFileSize(), new ArrayList<FileDescriptor>());
}
// Add file to the list
poolSizeMap.get(desc._poolURI).get(desc.getFileSize()).add(desc);
}
return poolSizeMap;
}
/**
* Return a List of URIs for the filesystems.
*
* @param descriptors List<FileDescriptors>
* @return List<URI> of filesystems in the input list
*/
public static List<URI> getFileSystemURIs(List<FileDescriptor> descriptors) {
List<URI> fileURIs = new ArrayList<URI>();
for (FileDescriptor desc : descriptors) {
fileURIs.add(desc._fsURI);
}
return fileURIs;
}
/**
* Filter a list of FileDescriptors by type(s).
*
* @param descriptors -- Original list.
* @param inclusive -- Types to be included (or null if not used).
* @param exclusive -- Types to be excluded (or null if not used).
* @return List<FileDescriptor>
*/
public static List<FileDescriptor> filterByType(
List<FileDescriptor> descriptors,
Type[] inclusive, Type[] exclusive) {
List<FileDescriptor> result = new ArrayList<FileDescriptor>();
if (descriptors == null) {
return result;
}
HashSet<Type> included = new HashSet<Type>();
if (inclusive != null) {
included.addAll(Arrays.asList(inclusive));
}
HashSet<Type> excluded = new HashSet<Type>();
if (exclusive != null) {
excluded.addAll(Arrays.asList(exclusive));
}
for (FileDescriptor desc : descriptors) {
if (excluded.contains(desc._type)) {
continue;
}
if (included.isEmpty() || included.contains(desc._type)) {
result.add(desc);
}
}
return result;
}
public static List<FileDescriptor> filterByType(
List<FileDescriptor> descriptors,
Type... inclusive) {
return filterByType(descriptors, inclusive, null);
}
}