/*
* Copyright (c) 2012-2015 iWave Software LLC
* All Rights Reserved
*/
/**
*
*/
package com.iwave.ext.netapp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.iwave.ext.netapp.model.ShareState;
import netapp.manage.NaElement;
import netapp.manage.NaServer;
/**
* @author sdorcas
* Not to be used directly by users or Orchestrator services. Use NetAppFacade.
*/
public class Lun {
private Logger log = Logger.getLogger(getClass());
private String path = "";
private NaServer server = null;
public Lun(NaServer server, String lunPath)
{
path = lunPath;
this.server = server;
}
/**
* Resize an existing LUN
*
* @param size - size in Bytes to resize the LUN
* @param force - forcibly reduce the size. Must be true to reduce size.
* @return - actual size of LUN.
* @throws NetAppException
*/
long resizeLun(long size, boolean force)
{
NaElement elem = new NaElement("lun-resize");
elem.addNewChild("force", Boolean.toString(force));
elem.addNewChild("path", path);
elem.addNewChild("size", Long.toString(size));
NaElement result = null;
try {
result = server.invokeElem(elem);
return result.getChildLongValue("actual-size", -1);
} catch (Exception e) {
String msg = "Failed to resize LUN path=" + path;
log.error(msg, e);
throw new NetAppException(msg, e);
}
}
/**
* Takes a LUN online or offline.
*
* @param onlineState - true to take LUN online; false to take LUN offline
* @param forceOnline - force LUN online, bypassing mapping conflict checks
* @return
* @throws NetAppException
*/
boolean setLunOnline(boolean onlineState, boolean forceOnline)
{
NaElement elem = null;
if (onlineState == isOnline()) {
// already in desired state
return true;
}
if (onlineState) { // take LUN online
elem = new NaElement("lun-online");
elem.addNewChild("path", path);
elem.addNewChild("force", Boolean.toString(forceOnline));
}
else { // take LUN offline
elem = new NaElement("lun-offline");
elem.addNewChild("path", path);
}
try {
server.invokeElem(elem);
return true;
} catch (Exception e) {
String msg = "Failed to change LUN online status path=" + path;
log.error(msg, e);
throw new NetAppException(msg, e);
}
}
/**
*
* @param osType - the OS type for the LUN. Its important this is the correct OS type.
* @param size - size in bytes for the new LUN
* @param reserveSpace - reserve the space
* @return - the actual size (bytes) of the newly created LUN.
* @throws NetAppException
*/
long createLunBySize(LunOSType osType, long size, boolean reserveSpace)
{
NaElement elem = new NaElement("lun-create-by-size");
elem.addNewChild("ostype", osType.apiName());
elem.addNewChild("path", path);
elem.addNewChild("size", Long.toString(size));
elem.addNewChild("space-reservation-enabled", Boolean.toString(reserveSpace));
NaElement result = null;
try {
result = server.invokeElem(elem);
return result.getChildLongValue("actual-size", -1);
} catch (Exception e) {
String msg = "Failed to create LUN path=" + path;
log.error(msg, e);
throw new NetAppException(msg, e);
}
}
/**
*
* @param force - forcibly destroy the LUN
* @return - true/success, false/failed
* @throws NetAppException
*/
boolean destroyLun(boolean force)
{
NaElement elem = new NaElement("lun-destroy");
elem.addNewChild("force", Boolean.toString(force));
elem.addNewChild("path", path);
try {
server.invokeElem(elem);
return true;
} catch (Exception e) {
String msg = "Failed to destroy LUN path=" + path;
log.error(msg, e);
throw new NetAppException(msg, e);
}
}
/**
* Retrieves the occupied size in bytes of the LUN.
*
* @return - the size, -1 if the operation failed.
* @throws NetAppException
*/
long getLunOccupiedSize()
{
NaElement elem = new NaElement("lun-get-occupied-size");
elem.addNewChild("path", path);
try {
NaElement result = server.invokeElem(elem);
return result.getChildLongValue("occupied-size", -1);
} catch (Exception e) {
String msg = "Failed to retrieve occupied size of LUN path=" + path;
log.error(msg, e);
throw new NetAppException(msg, e);
}
}
/**
* Map the LUN to initiators in the initiator group
*
* @param force - Forcibly map LUN, disabling conflict checks.
* @param initGroup - Initiator group to the specified LUN
* @param lunId - Lun ID to use when mapping to initiators. -1 means auto-assign.
* @return - the actual Lun ID assigned for this mapping. If not auto-assigned it should
* match the value provided if successful.
* @throws NetAppException
*/
int mapLun(boolean force, String initGroup, int lunId)
{
if (lunId == -1) {
log.info("LUN Id will be auto-assigned.");
}
NaElement elem = new NaElement("lun-map");
elem.addNewChild("force", Boolean.toString(force));
elem.addNewChild("initiator-group", initGroup);
if (lunId != -1) {
elem.addNewChild("lun-id", Integer.toString(lunId));
}
elem.addNewChild("path", path);
try {
NaElement result = server.invokeElem(elem);
return result.getChildIntValue("lun-id-assigned", -1);
} catch (Exception e) {
String msg = "Failed to map LUN path=" + path + " to group=" + initGroup;
log.error(msg, e);
throw new NetAppException(msg, e);
}
}
/**
* Unmaps a LUN from an initiatorGroup
*
* @param initGroup - name of initiator group
* @return - true if successful, false otherwise
* @throws NetAppException
*/
boolean unmapLun(String initGroup)
{
NaElement elem = new NaElement("lun-unmap");
elem.addNewChild("initiator-group", initGroup);
elem.addNewChild("path", path);
try {
server.invokeElem(elem);
return true;
} catch (Exception e) {
String msg = "Failed to unmap LUN path=" + path;
log.error(msg, e);
throw new NetAppException(msg, e);
}
}
/**
* Unmaps all initiator groups from the LUN. Mainly used prior to destroying the LUN.
*
* @throws NetAppException
*/
boolean unmapAll()
{
// First get all the initiator groups.
NaElement elem = new NaElement("lun-map-list-info");
elem.addNewChild("path", path);
NaElement result = null;
try {
result = server.invokeElem(elem).getChildByName("initiator-groups");
} catch (Exception e) {
String msg = "Failed unmapping all groups from LUN. Unable to retrieve list of maps for LUN path=" + path;
log.error(msg, e);
throw new NetAppException(msg, e);
}
// Now unmap each individually
boolean success = true;
for (NaElement el : (List<NaElement>) result.getChildren()) {
String iGroup = el.getChildContent("initiator-group-name");
try {
unmapLun(iGroup);
} catch (NetAppException e) {
success = false;
}
}
return success;
}
/**
* Sets a description on a LUN
*
* @param description
* @throws NetAppException
*/
void setLunDescription(String description)
{
NaElement elem = new NaElement("lun-set-comment");
elem.addNewChild("comment", description);
elem.addNewChild("path", path);
try {
server.invokeElem(elem);
} catch (Exception e) {
String msg = "Failed to set comment on LUN path=" + path;
log.error(msg, e);
throw new NetAppException(msg, e);
}
}
String getLunDescription() {
NaElement elem = new NaElement("lun-get-comment");
elem.addNewChild("path", path);
try {
return server.invokeElem(elem).getChildByName("comment").getContent();
} catch (Exception e) {
String msg = "Failed to set comment on LUN path=" + path;
log.error(msg, e);
throw new NetAppException(msg, e);
}
}
boolean isOnline() {
LunInfo info = listLUNs(false).get(0);
return info.isOnline();
}
/**
* @throws NetAppException
*/
int getLunIdForGroup(String initGroup)
{
Map<String, Integer> lunMap = getLunMap();
// Get the LUN id for the desired group
Integer id = lunMap.get(initGroup);
if (id == null) {
id = -1;
}
return id;
}
Map<String, Integer> getLunMap()
{
NaElement elem = new NaElement("lun-map-list-info");
elem.addNewChild("path", path);
NaElement result = null;
try {
result = server.invokeElem(elem).getChildByName("initiator-groups");
} catch (Exception e) {
String msg = "Failed to get LUN map list info";
log.error(msg, e);
throw new NetAppException(msg, e);
}
HashMap<String, Integer> map = new HashMap<String, Integer>();
for (NaElement el : (List<NaElement>) result.getChildren()) {
String group = el.getChildContent("initiator-group-name");
int id = el.getChildIntValue("lun-id", -1);
map.put(group, id);
}
return map;
}
/**
* @throws NetAppException
*/
List<LunInfo> listLUNs(boolean listAll)
{
ArrayList<LunInfo> luns = new ArrayList<LunInfo>();
NaElement elem = new NaElement("lun-list-info");
if (!listAll) {
elem.addNewChild("path", path);
}
NaElement result = null;
try {
result = server.invokeElem(elem).getChildByName("luns");
} catch (Exception e) {
String msg = "Failed to get LUN list info";
log.error(msg, e);
throw new NetAppException(msg, e);
}
// Create a LunInfo object for each LUN
for (NaElement lun : (List<NaElement>) result.getChildren()) {
LunInfo info = new LunInfo();
info.setPath(lun.getChildContent("path"));
info.setId(lun.getChildIntValue("device-id", -1));
info.setOnline(Boolean.valueOf(lun.getChildContent("online")));
info.setSize(lun.getChildLongValue("size", -1));
info.setSizeUsed(Long.parseLong(lun.getChildContent("size-used")));
info.setMapped(Boolean.valueOf(lun.getChildContent("mapped")));
info.setSpaceReserved(Boolean.valueOf(lun.getChildContent("is-space-reservation-enabled")));
info.setShareState(ShareState.valueOf(lun.getChildContent("share-state")));
info.setLunType(LunOSType.valueOf(lun.getChildContent("multiprotocol-type")));
luns.add(info);
}
return luns;
}
}