/*******************************************************************************
* Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com>
* This file is part of Gluster Management Console.
*
* Gluster Management Console is free software; you can redistribute
* it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Gluster Management Console is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*******************************************************************************/
package org.ovirt.engine.core.common.businessentities;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.ovirt.engine.core.common.businessentities.GlusterBrickEntity.BRICK_STATUS;
import org.ovirt.engine.core.common.constants.GlusterConstants;
import org.ovirt.engine.core.common.utils.GlusterCoreUtil;
import org.ovirt.engine.core.common.utils.StringUtil;
import org.ovirt.engine.core.compat.Guid;
public class GlusterVolumeEntity extends GlusterEntity implements BusinessEntity<String> {
public enum VOLUME_STATUS {
ONLINE,
OFFLINE
};
public enum VOLUME_TYPE {
DISTRIBUTE,
REPLICATE,
DISTRIBUTED_REPLICATE,
STRIPE,
DISTRIBUTED_STRIPE
};
public enum TRANSPORT_TYPE {
ETHERNET,
INFINIBAND
};
public enum ACCESS_PROTOCOL {
GLUSTER,
NFS,
CIFS
};
public static final int DEFAULT_REPLICA_COUNT = 2;
public static final int DEFAULT_STRIPE_COUNT = 4;
public static final String OPTION_AUTH_ALLOW = "auth.allow";
public static final String OPTION_NFS_DISABLE = "nfs.disable";
private static final String[] VOLUME_TYPE_STR = new String[] { "Distribute", "Replicate", "Distributed Replicate",
"Stripe", "Distributed Stripe" };
private static final String[] TRANSPORT_TYPE_STR = new String[] { "Ethernet", "Infiniband" };
private static final String[] STATUS_STR = new String[] { "Online", "Offline" };
private static final String[] ACCESS_PROTOCOL_STR = new String[] { "Gluster", "NFS", "CIFS" };
private VOLUME_TYPE volumeType;
private TRANSPORT_TYPE transportType;
private VOLUME_STATUS status;
private int replicaCount;
private int stripeCount;
private GlusterVolumeOptions options = new GlusterVolumeOptions();
private List<GlusterBrickEntity> bricks = new ArrayList<GlusterBrickEntity>();
private List<String> cifsUsers = new ArrayList<String>();
private Guid clusterId;
public GlusterVolumeEntity() {
}
// Only GlusterFS is enabled
private Set<ACCESS_PROTOCOL> accessProtocols = new LinkedHashSet<ACCESS_PROTOCOL>(Arrays.asList(new ACCESS_PROTOCOL[] {
ACCESS_PROTOCOL.GLUSTER }));
public String getVolumeTypeStr() {
return getVolumeTypeStr(getVolumeType());
}
public static String getVolumeTypeStr(VOLUME_TYPE volumeType) {
return VOLUME_TYPE_STR[volumeType.ordinal()];
}
public static VOLUME_TYPE getVolumeTypeByStr(String volumeTypeStr) {
return VOLUME_TYPE.valueOf(volumeTypeStr);
}
public static TRANSPORT_TYPE getTransportTypeByStr(String transportTypeStr) {
return TRANSPORT_TYPE.valueOf(transportTypeStr);
}
public String getTransportTypeStr() {
return TRANSPORT_TYPE_STR[getTransportType().ordinal()];
}
public String getStatusStr() {
return STATUS_STR[getStatus().ordinal()];
}
public int getNumOfBricks() {
return bricks.size();
}
public VOLUME_TYPE getVolumeType() {
return volumeType;
}
public void setVolumeType(VOLUME_TYPE volumeType) {
this.volumeType = volumeType;
if (volumeType == VOLUME_TYPE.DISTRIBUTED_STRIPE) {
setReplicaCount(0);
setStripeCount(DEFAULT_STRIPE_COUNT);
} else if (volumeType == VOLUME_TYPE.DISTRIBUTED_REPLICATE) {
setReplicaCount(DEFAULT_REPLICA_COUNT);
setStripeCount(0);
} else {
setReplicaCount(0);
setStripeCount(0);
}
}
public void setVolumeType(String volumeType) {
for(VOLUME_TYPE type : VOLUME_TYPE.values()) {
if(type.toString().equals(volumeType)) {
setVolumeType(type);
return;
}
}
}
public TRANSPORT_TYPE getTransportType() {
return transportType;
}
public void setTransportType(TRANSPORT_TYPE transportType) {
this.transportType = transportType;
}
public void setTransportType(String transportType) {
for(TRANSPORT_TYPE type : TRANSPORT_TYPE.values()) {
if(type.toString().equals(transportType)) {
setTransportType(type);
return;
}
}
}
public VOLUME_STATUS getStatus() {
return status;
}
public int getReplicaCount() {
return replicaCount;
}
public void setReplicaCount(int replicaCount) {
this.replicaCount = replicaCount;
}
public int getStripeCount() {
return stripeCount;
}
public void setStripeCount(int stripeCount) {
this.stripeCount = stripeCount;
}
public void setStatus(VOLUME_STATUS status) {
this.status = status;
}
public Set<ACCESS_PROTOCOL> getAccessProtocols() {
return accessProtocols;
}
public void setAccessProtocols(Set<ACCESS_PROTOCOL> accessProtocols) {
this.accessProtocols = accessProtocols;
}
public String getAccessProtocolsStr() {
String protocolsStr = "";
for (ACCESS_PROTOCOL protocol : accessProtocols) {
String protocolStr = ACCESS_PROTOCOL_STR[protocol.ordinal()];
protocolsStr += (protocolsStr.isEmpty() ? protocolStr : ", " + protocolStr);
}
return protocolsStr;
}
public void setAccessProtocols(String accessProtocols) {
if(accessProtocols == null || accessProtocols.trim().isEmpty()) {
this.accessProtocols = null;
return;
}
Set<ACCESS_PROTOCOL> protocols = new HashSet<GlusterVolumeEntity.ACCESS_PROTOCOL>();
String[] accessProtocolList = accessProtocols.split(",", -1);
for (String accessProtocol : accessProtocolList) {
protocols.add(ACCESS_PROTOCOL.valueOf(accessProtocol.trim()));
}
setAccessProtocols(protocols);
}
public String getAccessControlList() {
return options.get(OPTION_AUTH_ALLOW);
}
public void setAccessControlList(String accessControlList) {
setOption(OPTION_AUTH_ALLOW, accessControlList);
}
public boolean isNfsEnabled() {
String nfsDisabled = options.get(OPTION_NFS_DISABLE);
if (nfsDisabled == null || nfsDisabled.equalsIgnoreCase(GlusterConstants.OFF)) {
return true;
} else {
return false;
}
}
public GlusterVolumeOptions getOptions() {
return options;
}
public void setOption(String key, String value) {
options.put(key, value);
}
public void setOptions(GlusterVolumeOptions options) {
this.options = options;
}
public void setOptions(String options) {
if(options == null || options.trim().isEmpty()) {
this.options = new GlusterVolumeOptions();
return;
}
String[] optionArr = options.split(",", -1);
for(String option : optionArr) {
String[] optionInfo = option.split("=", -1);
setOption(optionInfo[0], optionInfo[1]);
}
}
public void setOptions(LinkedHashMap<String, String> options) {
List<GlusterVolumeOption> volumeOptions = new ArrayList<GlusterVolumeOption>();
for (Entry<String, String> entry : options.entrySet()) {
volumeOptions.add(new GlusterVolumeOption(entry.getKey(), entry.getValue()));
}
this.options.setOptions(volumeOptions);
}
public void addBrick(GlusterBrickEntity GlusterBrick) {
bricks.add(GlusterBrick);
}
public void addBrick(String brickQualifiedName) {
bricks.add(new GlusterBrickEntity(brickQualifiedName));
}
public void addBricks(Collection<GlusterBrickEntity> bricks) {
this.bricks.addAll(bricks);
}
public void setBricks(List<GlusterBrickEntity> bricks) {
this.bricks = bricks;
}
public void setBricks(String bricksStr) {
if(bricksStr == null || bricksStr.trim().isEmpty()) {
this.bricks = new ArrayList<GlusterBrickEntity>();
return;
}
String[] brickList = bricksStr.split(",", -1);
List<GlusterBrickEntity> bricks = new ArrayList<GlusterBrickEntity>();
for(String brick : brickList) {
String[] brickInfo = brick.split(":", -1);
bricks.add(new GlusterBrickEntity(brickInfo[0], BRICK_STATUS.ONLINE, brickInfo[1]));
}
setBricks(bricks);
}
public void removeBrick(GlusterBrickEntity GlusterBrick) {
bricks.remove(GlusterBrick);
}
public List<GlusterBrickEntity> getBricks() {
return bricks;
}
public void enableNFS() {
accessProtocols.add(ACCESS_PROTOCOL.NFS);
setOption(OPTION_NFS_DISABLE, GlusterConstants.OFF);
}
public void disableNFS() {
accessProtocols.remove(ACCESS_PROTOCOL.NFS);
setOption(OPTION_NFS_DISABLE, GlusterConstants.ON);
}
public void enableCifs() {
if (!accessProtocols.contains(ACCESS_PROTOCOL.CIFS)) {
accessProtocols.add(ACCESS_PROTOCOL.CIFS);
}
}
public void disableCifs() {
accessProtocols.remove(ACCESS_PROTOCOL.CIFS);
}
public boolean isCifsEnable() {
return accessProtocols.contains(ACCESS_PROTOCOL.CIFS);
}
public void setCifsUsers(List<String> cifsUsers) {
this.cifsUsers = cifsUsers;
}
public void setCifsUsers(String cifsUsers) {
if(cifsUsers == null || cifsUsers.trim().isEmpty()) {
this.cifsUsers = new ArrayList<String>();
return;
}
String[] userList = cifsUsers.split(",", -1);
List<String> users = new ArrayList<String>();
for(String user : userList) {
users.add(user.trim());
}
setCifsUsers(users);
}
public List<String> getCifsUsers() {
return cifsUsers;
}
public GlusterVolumeEntity(String name,
GlusterEntity parent,
VOLUME_TYPE volumeType,
TRANSPORT_TYPE transportType,
VOLUME_STATUS status) {
setVolumeType(volumeType);
setTransportType(transportType);
setStatus(status);
}
/**
* Filter matches if any of the properties name, GlusterVolume type, transport type, status and number of disks
* contains the filter string
*/
@Override
public boolean filter(String filterString, boolean caseSensitive) {
return StringUtil.filterString(getName() + getVolumeTypeStr() + getTransportTypeStr() + getStatusStr()
+ getNumOfBricks(), filterString, caseSensitive);
}
public List<String> getBrickDirectories() {
List<String> brickDirectories = new ArrayList<String>();
for (GlusterBrickEntity brick : getBricks()) {
brickDirectories.add(brick.getQualifiedName());
}
return brickDirectories;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof GlusterVolumeEntity)) {
return false;
}
GlusterVolumeEntity volume = (GlusterVolumeEntity) obj;
if (!(getName().equals(volume.getName()) && getVolumeType() == volume.getVolumeType()
&& getTransportType() == volume.getTransportType() && getStatus() == volume.getStatus()
&& getReplicaCount() == volume.getReplicaCount()
&& getStripeCount() == volume.getStripeCount()
&& getOptions().equals(volume.getOptions()))) {
return false;
}
for (ACCESS_PROTOCOL nasProtocol : getAccessProtocols()) {
if (!(volume.getAccessProtocols().contains(nasProtocol))) {
return false;
}
}
List<GlusterBrickEntity> oldBricks = getBricks();
List<GlusterBrickEntity> newBricks = volume.getBricks();
if (oldBricks.size() != newBricks.size()) {
return false;
}
if (!GlusterCoreUtil.getAddedEntities(oldBricks, newBricks, false).isEmpty()) {
return false;
}
if (!GlusterCoreUtil.getAddedEntities(newBricks, oldBricks, false).isEmpty()) {
return false;
}
Map<GlusterBrickEntity, GlusterBrickEntity> modifiedBricks = GlusterCoreUtil.getModifiedEntities(oldBricks, newBricks);
if (modifiedBricks.size() > 0) {
return false;
}
return true;
}
/**
* Note: this method doesn't copy the bricks. Clients should write separate code to identify added/removed/modified
* bricks and update the GlusterVolume bricks appropriately.
*
* @param newVolume
*/
public void copyFrom(GlusterVolumeEntity newVolume) {
setName(newVolume.getName());
setVolumeType(newVolume.getVolumeType());
setTransportType(newVolume.getTransportType());
setStatus(newVolume.getStatus());
setReplicaCount(newVolume.getReplicaCount());
setStripeCount(newVolume.getStripeCount());
setAccessProtocols(newVolume.getAccessProtocols());
setCifsUsers(newVolume.getCifsUsers());
getOptions().copyFrom(newVolume.getOptions());
}
@Override
public Object getQueryableId() {
return getId();
}
public Guid getClusterId() {
return clusterId;
}
public void setClusterId(Guid clusterId) {
this.clusterId = clusterId;
}
}