/*
* Copyright (c) 2014 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.hds.api;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpStatus;
import org.milyn.payload.JavaResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.emc.storageos.hds.HDSConstants;
import com.emc.storageos.hds.HDSException;
import com.emc.storageos.hds.model.Add;
import com.emc.storageos.hds.model.ConfigFile;
import com.emc.storageos.hds.model.Delete;
import com.emc.storageos.hds.model.EchoCommand;
import com.emc.storageos.hds.model.Error;
import com.emc.storageos.hds.model.Get;
import com.emc.storageos.hds.model.HDSHost;
import com.emc.storageos.hds.model.Modify;
import com.emc.storageos.hds.model.ReplicationGroup;
import com.emc.storageos.hds.model.ReplicationInfo;
import com.emc.storageos.hds.model.SnapshotGroup;
import com.emc.storageos.hds.util.SmooksUtil;
import com.emc.storageos.hds.xmlgen.InputXMLGenerationClient;
import com.google.gson.internal.Pair;
import com.sun.jersey.api.client.ClientResponse;
public class HDSApiProtectionManager {
/**
* Logger instance to log messages.
*/
private static final Logger log = LoggerFactory.getLogger(HDSApiProtectionManager.class);
public static enum ShadowImageOperationType {
split,
resync,
restore
}
private HDSApiClient hdsApiClient;
public HDSApiProtectionManager(HDSApiClient hdsApiClient) {
this.hdsApiClient = hdsApiClient;
}
/**
* Returns ViPR-Replication-Group objectID collected from Device manager to create ShadowImage pair on
* Hitachi StorageSystem.
*
* @return replicationGroup's objectID
* @throws Exception
*/
public String getReplicationGroupObjectId() throws Exception {
List<HDSHost> hostList = getHDSHostList();
String replicationGroupObjectId = null;
HDSHost pairMgmtServer = null;
if (hostList != null) {
outerloop: for (HDSHost hdsHost : hostList) {
log.info("HDSHost :{}", hdsHost.toXMLString());
if (hdsHost != null && hdsHost.getConfigFileList() != null
&& !hdsHost.getConfigFileList().isEmpty()) {
for (ConfigFile configFile : hdsHost.getConfigFileList()) {
if (configFile != null) {
ReplicationGroup replicationGroup = configFile.getReplicationGroup();
if (replicationGroup != null
&& HDSConstants.VIPR_REPLICATION_GROUP_NAME.equalsIgnoreCase(replicationGroup.getGroupName())) {
pairMgmtServer = hdsHost;
log.info("Pair management server {} found", pairMgmtServer.getName());
replicationGroupObjectId = replicationGroup.getObjectID();
log.info("ViPR Replication Group {} found", replicationGroup.toXMLString());
break outerloop;
}
}
}
}
}
}
return replicationGroupObjectId;
}
/**
* Return's replicationGroup's objectID and replicationInfo's objectID for the given P-VOl and S-VOL
*
* @param primaryVolumeNativeId
* @param secondaryVolumeNativeId
* @return {@link Map} replicationGroup's objectID and replicationInfo's objectID
* @throws Exception
*/
public Map<String, String> getReplicationRelatedObjectIds(String primaryVolumeNativeId,
String secondaryVolumeNativeId) throws Exception {
Map<String, String> objectIds = new HashMap<>();
log.info("primaryVolumeNativeId :{}", primaryVolumeNativeId);
log.info("secondaryVolumeNativeId :{}", secondaryVolumeNativeId);
List<HDSHost> hostList = getHDSHostList();
if (hostList != null) {
for (HDSHost hdsHost : hostList) {
log.info("HDSHost :{}", hdsHost.toXMLString());
if (hdsHost != null && hdsHost.getConfigFileList() != null
&& !hdsHost.getConfigFileList().isEmpty()) {
for (ConfigFile configFile : hdsHost.getConfigFileList()) {
if (configFile != null) {
ReplicationGroup replicationGroup = configFile.getReplicationGroup();
if (replicationGroup != null && replicationGroup.getReplicationInfoList() != null) {
log.debug("replicationGroup :{}", replicationGroup.toXMLString());
List<ReplicationInfo> replicationInfoList = replicationGroup.
getReplicationInfoList();
if (replicationInfoList != null) {
for (ReplicationInfo replicationInfo : replicationInfoList) {
log.debug("replicationInfo :{}", replicationInfo.toXMLString());
if (primaryVolumeNativeId.equalsIgnoreCase(replicationInfo.getPvolDevNum())
&& secondaryVolumeNativeId.equalsIgnoreCase(replicationInfo.getSvolDevNum())) {
objectIds.put(HDSConstants.REPLICATION_INFO_OBJ_ID, replicationInfo.getObjectID());
objectIds.put(HDSConstants.REPLICATION_GROUP_OBJ_ID, replicationGroup.getObjectID());
log.info("objectIds :{}", objectIds);
return objectIds;
}
}
}
}
}
}
}
}
}
log.error("Unable to get replication information from pair management server");
return objectIds;
}
public Pair<ReplicationInfo, String> getReplicationInfoFromSystem(String sourceNativeId, String targetNativeId) throws Exception {
log.info("sourceNativeId :{}", sourceNativeId);
log.info("targetNativeId :{}", targetNativeId);
List<HDSHost> hostList = getHDSHostList();
if (hostList != null) {
for (HDSHost hdsHost : hostList) {
log.info("HDSHost :{}", hdsHost.toXMLString());
if (hdsHost != null && hdsHost.getConfigFileList() != null
&& !hdsHost.getConfigFileList().isEmpty()) {
for (ConfigFile configFile : hdsHost.getConfigFileList()) {
if (configFile != null) {
ReplicationGroup replicationGroup = configFile.getReplicationGroup();
if (replicationGroup != null && replicationGroup.getReplicationInfoList() != null) {
log.info("replicationGroup :{}", replicationGroup.toXMLString());
List<ReplicationInfo> replicationInfoList = replicationGroup.
getReplicationInfoList();
if (replicationInfoList != null) {
for (ReplicationInfo replicationInfo : replicationInfoList) {
log.debug("replicationInfo :{}", replicationInfo.toXMLString());
if (sourceNativeId.equals(replicationInfo.getPvolDevNum())
&& targetNativeId.equals(replicationInfo.getSvolDevNum())) {
log.info("Found replicationInfo object from system:{}", replicationInfo.toXMLString());
log.info("Host Object Id :{}", hdsHost.getObjectID());
return (new Pair<ReplicationInfo, String>(replicationInfo, hdsHost.getObjectID()));
}
}
}
}
}
}
}
}
}
// If we are here there is no matching replication info available on pair management server.
log.error("Unable to find replication info details from device manager for the pvol {} svol {}", sourceNativeId, targetNativeId);
return null;
}
/**
* Returns Host List collected from Device Manager.
*
* @return
* @throws Exception
*/
private List<HDSHost> getHDSHostList() throws Exception {
List<HDSHost> hostList = null;
InputStream responseStream = null;
try {
Map<String, Object> attributeMap = new HashMap<String, Object>();
Get getOp = new Get(HDSConstants.HOST);
attributeMap.put(HDSConstants.GET, getOp);
HDSHost host = new HDSHost();
host.setName("*");
attributeMap.put(HDSConstants.HOST, host);
String getAllHSDQuery = InputXMLGenerationClient.getInputXMLString(
HDSConstants.GET_ALL_HOST_INFO_OP, attributeMap,
HDSConstants.HITACHI_INPUT_XML_CONTEXT_FILE,
HDSConstants.HITACHI_SMOOKS_CONFIG_FILE);
log.info("Query to get All Host: {}", getAllHSDQuery);
URI endpointURI = hdsApiClient.getBaseURI();
ClientResponse response = hdsApiClient.post(endpointURI, getAllHSDQuery);
if (HttpStatus.SC_OK == response.getStatus()) {
responseStream = response.getEntityInputStream();
JavaResult javaResult = SmooksUtil.getParsedXMLJavaResult(responseStream,
HDSConstants.HOST_INFO_SMOOKS_CONFIG_FILE);
hdsApiClient.verifyErrorPayload(javaResult);
hostList = (List<HDSHost>) javaResult.getBean(HDSConstants.HOST_LIST_BEAN_NAME);
} else {
throw HDSException.exceptions
.invalidResponseFromHDS(String
.format("Not able to query HostStorageDomain's due to invalid response %1$s from server",
response.getStatus()));
}
} finally {
if (null != responseStream) {
try {
responseStream.close();
} catch (IOException e) {
log.warn("IOException occurred while closing the response stream");
}
}
}
return hostList;
}
/**
* Creates ShadowImage Pair
*
* @param replicationGroupObjId
* @param pairName
* @param arrayType
* @param arraySerialNumber
* @param pvolDevNum
* @param svolDevNum
* @param model
* @return {@link ReplicationInfo}
*/
public ReplicationInfo createShadowImagePair(String replicationGroupObjId, String pairName, String arrayType,
String arraySerialNumber, String pvolDevNum, String svolDevNum, String model) throws Exception {
log.info("Shadow Image pair creation started");
InputStream responseStream = null;
ReplicationInfo replicationInfoResponse = null;
String syncTaskMessageId = null;
try {
log.info("replicationGroupObjId {} "
, replicationGroupObjId);
log.info("arrayType {} arraySerialNumber {}", arrayType, arraySerialNumber);
log.info(" pvolDevNum {} svolDevNum {}", pvolDevNum, svolDevNum);
Map<String, Object> attributeMap = new HashMap<String, Object>();
Add addOp = new Add(HDSConstants.REPLICATION);
ReplicationGroup replicationGroup = new ReplicationGroup();
replicationGroup.setObjectID(replicationGroupObjId);
replicationGroup.setReplicationFunction(HDSConstants.SHADOW_IMAGE);
ReplicationInfo replicationInfo = new ReplicationInfo();
replicationInfo.setPairName(pairName);
replicationInfo.setPvolArrayType(arrayType);
replicationInfo.setPvolSerialNumber(arraySerialNumber);
replicationInfo.setPvolDevNum(pvolDevNum);
replicationInfo.setSvolArrayType(arrayType);
replicationInfo.setSvolSerialNumber(arraySerialNumber);
replicationInfo.setSvolDevNum(svolDevNum);
replicationInfo.setReplicationFunction(HDSConstants.SHADOW_IMAGE);
attributeMap.put(HDSConstants.ADD, addOp);
attributeMap.put(HDSConstants.MODEL, model);
attributeMap.put(HDSConstants.REPLICATION_GROUP, replicationGroup);
attributeMap.put(HDSConstants.REPLICATION_INFO, replicationInfo);
String createShadowImagePairInputXML = InputXMLGenerationClient.getInputXMLString(
HDSConstants.CREATE_SHADOW_IMAGE_PAIR_OP, attributeMap,
HDSConstants.HITACHI_INPUT_XML_CONTEXT_FILE,
HDSConstants.HITACHI_SMOOKS_CONFIG_FILE);
log.info("Query to create shadow image pair volume: {}", createShadowImagePairInputXML);
URI endpointURI = hdsApiClient.getBaseURI();
ClientResponse response = hdsApiClient.post(endpointURI, createShadowImagePairInputXML);
if (HttpStatus.SC_OK == response.getStatus()) {
responseStream = response.getEntityInputStream();
JavaResult result = SmooksUtil.getParsedXMLJavaResult(responseStream, HDSConstants.HITACHI_SMOOKS_REPLICATION_CONFIG_FILE);
EchoCommand command = result.getBean(EchoCommand.class);
if (HDSConstants.COMPLETED_STR.equalsIgnoreCase(command.getStatus())) {
log.info("ShadowImage Pair has been created successfully");
replicationInfoResponse = result.getBean(ReplicationInfo.class);
if (null == replicationInfoResponse) {
throw HDSException.exceptions.notAbleToCreateShadowImagePair();
}
} else if (HDSConstants.PROCESSING_STR.equalsIgnoreCase(command.getStatus())) {
syncTaskMessageId = command.getMessageID();
} else if (HDSConstants.FAILED_STR.equalsIgnoreCase(command.getStatus())) {
Error error = result.getBean(Error.class);
log.error("Shadow Image pair creation failed status messageID: {}", command.getMessageID());
log.error("Shadow Image pair creation failed with error code: {} with message: {}", error.getCode(),
error.getDescription());
throw HDSException.exceptions.notAbleToCreateVolume(
error.getCode(), error.getDescription());
}
} else {
log.error("Shadow Image pair creation failed with invalid response code {}",
response.getStatus());
throw HDSException.exceptions
.invalidResponseFromHDS(String
.format("Shadow Image pair creation failed due to invalid response %1$s from server for system %2$s",
response.getStatus(), arraySerialNumber));
}
} finally {
if (null != responseStream) {
try {
responseStream.close();
} catch (IOException e) {
log.warn("Exception occurred while close Shadow Image Pair creation response stream");
}
}
}
log.info("Shadow Image pair creation completed");
return replicationInfoResponse;
}
/**
* Creates ThinImage pair for HDS Snapshot
*
* @param snapshotGroupObjId
* @param hostObjId
* @param sourNativeId
* @param snapNativeId
* @param thinImagePoolId
* @return
* @throws Exception
*/
public boolean createThinImagePair(String snapshotGroupObjId, String hostObjId,
String sourNativeId, String snapNativeId, String thinImagePoolId, String model) throws Exception {
log.info("Thin Image pair creation started");
boolean status = false;
InputStream responseStream = null;
String syncTaskMessageId = null;
try {
log.info("snapshotGroupObjId {} "
, snapshotGroupObjId);
Map<String, Object> attributeMap = new HashMap<String, Object>();
Add addOp = new Add(HDSConstants.REPLICATION);
addOp.setOption(HDSConstants.INBAND2);
HDSHost host = new HDSHost();
host.setObjectID(hostObjId);
SnapshotGroup snapshotGroup = new SnapshotGroup();
snapshotGroup.setObjectID(snapshotGroupObjId);
snapshotGroup.setReplicationFunction(HDSConstants.THIN_IMAGE);
ReplicationInfo replicationInfo = new ReplicationInfo();
replicationInfo.setPvolDevNum(sourNativeId);
replicationInfo.setSvolDevNum(snapNativeId);
replicationInfo.setPvolPoolID(thinImagePoolId);
attributeMap.put(HDSConstants.ADD, addOp);
attributeMap.put(HDSConstants.MODEL, model);
attributeMap.put(HDSConstants.HOST, host);
attributeMap.put(HDSConstants.SNAPSHOTGROUP, snapshotGroup);
attributeMap.put(HDSConstants.REPLICATION_INFO, replicationInfo);
String createThinImagePairInputXML = InputXMLGenerationClient.getInputXMLString(
HDSConstants.CREATE_THIN_IMAGE_PAIR_OP, attributeMap,
HDSConstants.HITACHI_INPUT_XML_CONTEXT_FILE,
HDSConstants.HITACHI_SMOOKS_CONFIG_FILE);
log.info("Query to create thin image pair : {}", createThinImagePairInputXML);
URI endpointURI = hdsApiClient.getBaseURI();
ClientResponse response = hdsApiClient.post(endpointURI, createThinImagePairInputXML);
if (HttpStatus.SC_OK == response.getStatus()) {
responseStream = response.getEntityInputStream();
JavaResult result = SmooksUtil.getParsedXMLJavaResult(responseStream, HDSConstants.HITACHI_SMOOKS_THINIMAGE_CONFIG_FILE);
EchoCommand command = result.getBean(EchoCommand.class);
if (HDSConstants.COMPLETED_STR.equalsIgnoreCase(command.getStatus())) {
log.info("ThinImage Pair has been created successfully");
status = true;
SnapshotGroup snapshotGrpResponse = result.getBean(SnapshotGroup.class);
if (null == snapshotGrpResponse) {
throw HDSException.exceptions.notAbleToCreateThinImagePair();
}
} else if (HDSConstants.PROCESSING_STR.equalsIgnoreCase(command.getStatus())) {
syncTaskMessageId = command.getMessageID();
} else if (HDSConstants.FAILED_STR.equalsIgnoreCase(command.getStatus())) {
Error error = result.getBean(Error.class);
log.error("Thin Image pair creation failed status messageID: {}", command.getMessageID());
log.error("Thin Image pair creation failed with error code: {} with message: {}", error.getCode(),
error.getDescription());
throw HDSException.exceptions.notAbleToCreateThinImagePairError(
error.getCode(), error.getDescription());
}
} else {
log.error("Thin Image pair creation failed with invalid response code {}",
response.getStatus());
throw HDSException.exceptions
.invalidResponseFromHDS(String
.format("Thin Image pair creation failed due to invalid response %1$s from server",
response.getStatus()));
}
} finally {
if (null != responseStream) {
try {
responseStream.close();
} catch (IOException e) {
log.warn("Exception occurred while close Thin Image Pair creation response stream");
}
}
}
log.info("Thin Image pair creation completed");
return status;
}
/**
* Modify ShadowImage pair operation .
*
* @param replicationGroupId
* @param replicationInfoId
* @param operationType
* @return {@link ReplicationInfo}
* @throws Exception
*/
public ReplicationInfo modifyShadowImagePair(String replicationGroupId, String replicationInfoId,
ShadowImageOperationType operationType, String model) throws Exception {
InputStream responseStream = null;
ReplicationInfo replicationInfo = null;
try {
if (replicationGroupId != null && replicationInfoId != null) {
Map<String, Object> attributeMap = new HashMap<String, Object>();
Modify modifyOp = new Modify();
modifyOp.setTarget(HDSConstants.REPLICATION);
modifyOp.setOption(operationType.name());
ReplicationGroup replicationGroup = new ReplicationGroup();
replicationGroup.setObjectID(replicationGroupId);
replicationInfo = new ReplicationInfo();
replicationInfo.setObjectID(replicationInfoId);
attributeMap.put(HDSConstants.MODIFY, modifyOp);
attributeMap.put(HDSConstants.MODEL, model);
attributeMap.put(HDSConstants.REPLICATION_GROUP, replicationGroup);
attributeMap.put(HDSConstants.REPLICATION_INFO, replicationInfo);
String modifyPairQuery = InputXMLGenerationClient.getInputXMLString(
HDSConstants.MODIFY_SHADOW_IMAGE_PAIR_OP, attributeMap,
HDSConstants.HITACHI_INPUT_XML_CONTEXT_FILE,
HDSConstants.HITACHI_SMOOKS_CONFIG_FILE);
log.info("Query to {} shadow image pair Query: {}", operationType.name(), modifyPairQuery);
URI endpointURI = hdsApiClient.getBaseURI();
ClientResponse response = hdsApiClient.post(endpointURI, modifyPairQuery);
if (HttpStatus.SC_OK == response.getStatus()) {
responseStream = response.getEntityInputStream();
JavaResult javaResult = SmooksUtil.getParsedXMLJavaResult(responseStream,
HDSConstants.HITACHI_SMOOKS_REPLICATION_CONFIG_FILE);
verifyErrorPayload(javaResult);
log.info("Successfully {}ed pair", operationType.name());
replicationInfo = javaResult.getBean(ReplicationInfo.class);
log.info("replicationInfo :{}", replicationInfo);
/*
* if (null == replicationInfo) {
* throw HDSException.exceptions.notAbleToCreateShadowImagePair();
* }
*/
} else {
throw HDSException.exceptions
.invalidResponseFromHDS(String
.format("Not able to modify replication info due to invalid response %1$s from server",
response.getStatus()));
}
}
} finally {
if (null != responseStream) {
try {
responseStream.close();
} catch (IOException e) {
log.warn("IOException occurred while closing the response stream");
}
}
}
return replicationInfo;
}
/**
* Utility method to check if there are any errors or not.
*
* @param javaResult
* @throws Exception
*/
private void verifyErrorPayload(JavaResult javaResult) throws Exception {
EchoCommand command = javaResult.getBean(EchoCommand.class);
if (null == command || null == command.getStatus()
|| HDSConstants.FAILED_STR.equalsIgnoreCase(command.getStatus())) {
Error error = javaResult.getBean(Error.class);
log.info("Error response received from Hitachi server for messageID", command.getMessageID());
log.info("Hitachi command failed with error code:{} with message:{} for request:{}",
new Object[] { error.getCode().toString(), error.getDescription(), error.getSource() });
throw HDSException.exceptions.errorResponseReceived(
error.getCode(), error.getDescription());
}
}
/**
* Deletes SI replicationInfo instance from replication group
*
* @param replicationGroupObjId
* @param replicationInfoObjId
* @return {@link ReplicationInfo}
* @throws Exception
*/
public ReplicationInfo deleteShadowImagePair(String replicationGroupObjId, String replicationInfoObjId, String model) throws Exception {
InputStream responseStream = null;
ReplicationInfo replicationInfo = null;
try {
if (replicationGroupObjId != null && replicationInfoObjId != null) {
Map<String, Object> attributeMap = new HashMap<String, Object>();
Delete deleteOp = new Delete(HDSConstants.REPLICATION);
ReplicationGroup replicationGroup = new ReplicationGroup();
replicationGroup.setObjectID(replicationGroupObjId);
replicationInfo = new ReplicationInfo();
replicationInfo.setObjectID(replicationInfoObjId);
attributeMap.put(HDSConstants.DELETE, deleteOp);
attributeMap.put(HDSConstants.MODEL, model);
attributeMap.put(HDSConstants.REPLICATION_GROUP, replicationGroup);
attributeMap.put(HDSConstants.REPLICATION_INFO, replicationInfo);
String deletePairQuery = InputXMLGenerationClient.getInputXMLString(
HDSConstants.DELETE_PAIR_OP, attributeMap,
HDSConstants.HITACHI_INPUT_XML_CONTEXT_FILE,
HDSConstants.HITACHI_SMOOKS_CONFIG_FILE);
log.info("Query to delete shadow image pair Query: {}", deletePairQuery);
URI endpointURI = hdsApiClient.getBaseURI();
ClientResponse response = hdsApiClient.post(endpointURI, deletePairQuery);
if (HttpStatus.SC_OK == response.getStatus()) {
responseStream = response.getEntityInputStream();
JavaResult javaResult = SmooksUtil.getParsedXMLJavaResult(responseStream,
HDSConstants.HITACHI_SMOOKS_REPLICATION_CONFIG_FILE);
verifyErrorPayload(javaResult);
log.info("Successfully Deleted pair");
replicationInfo = javaResult.getBean(ReplicationInfo.class);
log.info("replicationInfo :{}", replicationInfo);
/*
* if (null == replicationInfo) {
* throw HDSException.exceptions.notAbleToCreateShadowImagePair();
* }
*/
} else {
throw HDSException.exceptions
.invalidResponseFromHDS(String
.format("Not able to delete shadow image pair due to invalid response %1$s from server",
response.getStatus()));
}
} else {
log.info("Replication info is not available on pair management server");
}
} finally {
if (null != responseStream) {
try {
responseStream.close();
} catch (IOException e) {
log.warn("IOException occurred while closing the response stream");
}
}
}
return replicationInfo;
}
/**
* Deletes ReplicationInfo instance from SnapshotGroup
*
* @param snapshotGroupObjId
* @param replicationInfoObjId
* @throws Exception
*/
public void deleteThinImagePair(String hostObjId, String snapshotGroupObjId,
String replicationInfoObjId, String model) throws Exception {
InputStream responseStream = null;
ReplicationInfo replicationInfo = null;
try {
if (hostObjId != null && snapshotGroupObjId != null && replicationInfoObjId != null) {
Map<String, Object> attributeMap = new HashMap<String, Object>();
Delete deleteOp = new Delete(HDSConstants.REPLICATION, HDSConstants.INBAND2);
HDSHost host = new HDSHost();
host.setObjectID(hostObjId);
SnapshotGroup snapshotGroup = new SnapshotGroup();
snapshotGroup.setObjectID(snapshotGroupObjId);
replicationInfo = new ReplicationInfo();
replicationInfo.setObjectID(replicationInfoObjId);
attributeMap.put(HDSConstants.DELETE, deleteOp);
attributeMap.put(HDSConstants.HOST, host);
attributeMap.put(HDSConstants.MODEL, model);
attributeMap.put(HDSConstants.SNAPSHOTGROUP, snapshotGroup);
attributeMap.put(HDSConstants.REPLICATION_INFO, replicationInfo);
String deleteThinImagePairInputXML = InputXMLGenerationClient.getInputXMLString(
HDSConstants.DELETE_THIN_IMAGE_PAIR_OP, attributeMap,
HDSConstants.HITACHI_INPUT_XML_CONTEXT_FILE,
HDSConstants.HITACHI_SMOOKS_CONFIG_FILE);
log.info("Query to delete thin image pair : {}", deleteThinImagePairInputXML);
URI endpointURI = hdsApiClient.getBaseURI();
ClientResponse response = hdsApiClient.post(endpointURI, deleteThinImagePairInputXML);
if (HttpStatus.SC_OK == response.getStatus()) {
responseStream = response.getEntityInputStream();
JavaResult result = SmooksUtil.getParsedXMLJavaResult(responseStream,
HDSConstants.HITACHI_SMOOKS_THINIMAGE_CONFIG_FILE);
verifyErrorPayload(result);
log.info("Thin Image pair deleted successfully.");
} else {
log.error("Thin Image pair deletion failed with invalid response code {}",
response.getStatus());
throw HDSException.exceptions
.invalidResponseFromHDS(String
.format("Thin Image pair deletion failed due to invalid response %1$s from server",
response.getStatus()));
}
}
} finally {
if (null != responseStream) {
try {
responseStream.close();
} catch (IOException e) {
log.warn("IOException occurred while closing the response stream");
}
}
}
}
/**
* Get PairManagement Server for SnapshotGroup
*
* @param serialNumber
* @return
* @throws Exception
*/
public HDSHost getSnapshotGroupPairManagementServer(String serialNumber) throws Exception {
InputStream responseStream = null;
try {
log.info("Started to collect Pair Mgmt Server details");
Map<String, Object> attributeMap = new HashMap<String, Object>();
Get getOp = new Get(HDSConstants.HOST);
attributeMap.put(HDSConstants.GET, getOp);
HDSHost host = new HDSHost();
host.setName("*");
attributeMap.put(HDSConstants.HOST, host);
SnapshotGroup snapshotGroup = new SnapshotGroup();
// snapshotGroup.setArrayType(arrayType);
snapshotGroup.setSerialNumber(serialNumber);
snapshotGroup.setGroupName(HDSConstants.VIPR_SNAPSHOT_GROUP_NAME);
attributeMap.put(HDSConstants.SNAPSHOTGROUP, snapshotGroup);
String getSnapshotGroupQuery = InputXMLGenerationClient.getInputXMLString(
HDSConstants.GET_SNAPSHOT_GROUP_INFO_OP, attributeMap,
HDSConstants.HITACHI_INPUT_XML_CONTEXT_FILE,
HDSConstants.HITACHI_SMOOKS_CONFIG_FILE);
log.info("Query to pair management server Host: {}", getSnapshotGroupQuery);
URI endpointURI = hdsApiClient.getBaseURI();
ClientResponse response = hdsApiClient.post(endpointURI, getSnapshotGroupQuery);
if (HttpStatus.SC_OK == response.getStatus()) {
responseStream = response.getEntityInputStream();
JavaResult javaResult = SmooksUtil.getParsedXMLJavaResult(responseStream,
HDSConstants.HITACHI_SMOOKS_THINIMAGE_CONFIG_FILE);
hdsApiClient.verifyErrorPayload(javaResult);
List<HDSHost> hostList = (List<HDSHost>) javaResult.getBean(HDSConstants.HOST_LIST_BEAN_NAME);
log.info("Host List size :{}", hostList.size());
for (HDSHost hdsHost : hostList) {
if (hdsHost != null && hdsHost.getSnapshotGroupList() != null) {
log.info("Host Name :{}", hdsHost.getName());
for (SnapshotGroup snapGroup : hdsHost.getSnapshotGroupList()) {
log.info("SnapshotGroup groupName :{}", snapGroup.getGroupName());
if (snapGroup != null &&
HDSConstants.VIPR_SNAPSHOT_GROUP_NAME.equalsIgnoreCase(snapGroup.getGroupName())
&& serialNumber.equalsIgnoreCase(snapGroup.getSerialNumber())) {
log.info("Found ViPR snaphot group on pair mgmt server {}", hdsHost.getName());
return hdsHost;
}
}
}
}
} else {
throw HDSException.exceptions
.invalidResponseFromHDS(String
.format("Not able to query HostStorageDomain's due to invalid response %1$s from server",
response.getStatus()));
}
} finally {
if (null != responseStream) {
try {
responseStream.close();
} catch (IOException e) {
log.warn("IOException occurred while closing the response stream");
}
}
}
// If we are here there is no pair mgmt server available on storage system.
return null;
}
/**
* Restore's snapshot to source volume.
*
* @param pairMgmtServerHostObjId
* @param snapshotGroupObjId
* @param replicationInfoObjId
* @return
* @throws Exception
*/
public boolean restoreThinImagePair(String pairMgmtServerHostObjId, String snapshotGroupObjId,
String replicationInfoObjId, String model) throws Exception {
InputStream responseStream = null;
ReplicationInfo replicationInfo = null;
boolean status = false;
try {
if (pairMgmtServerHostObjId != null && snapshotGroupObjId != null && replicationInfoObjId != null) {
log.info("Restore thin image pair started");
Map<String, Object> attributeMap = new HashMap<String, Object>();
Modify modifyOp = new Modify(HDSConstants.REPLICATION);
modifyOp.setOption(HDSConstants.RESTORE_INBAND2);
HDSHost host = new HDSHost();
host.setObjectID(pairMgmtServerHostObjId);
SnapshotGroup snapshotGroup = new SnapshotGroup();
snapshotGroup.setObjectID(snapshotGroupObjId);
replicationInfo = new ReplicationInfo();
replicationInfo.setObjectID(replicationInfoObjId);
attributeMap.put(HDSConstants.MODIFY, modifyOp);
attributeMap.put(HDSConstants.MODEL, model);
attributeMap.put(HDSConstants.HOST, host);
attributeMap.put(HDSConstants.SNAPSHOTGROUP, snapshotGroup);
attributeMap.put(HDSConstants.REPLICATION_INFO, replicationInfo);
String restoreThinImagePairQuery = InputXMLGenerationClient.getInputXMLString(
HDSConstants.RESTORE_THIN_IMAGE_PAIR_OP, attributeMap,
HDSConstants.HITACHI_INPUT_XML_CONTEXT_FILE,
HDSConstants.HITACHI_SMOOKS_CONFIG_FILE);
log.info("Query to restore thin image pair Query: {}", restoreThinImagePairQuery);
URI endpointURI = hdsApiClient.getBaseURI();
ClientResponse response = hdsApiClient.post(endpointURI, restoreThinImagePairQuery);
if (HttpStatus.SC_OK == response.getStatus()) {
responseStream = response.getEntityInputStream();
JavaResult javaResult = SmooksUtil.getParsedXMLJavaResult(responseStream,
HDSConstants.HITACHI_SMOOKS_THINIMAGE_CONFIG_FILE);
verifyErrorPayload(javaResult);
log.info("Successfully restored thin image pair");
status = true;
replicationInfo = javaResult.getBean(ReplicationInfo.class);
log.info("replicationInfo :{}", replicationInfo);
/*
* if (null == replicationInfo) {
* throw HDSException.exceptions.notAbleToCreateShadowImagePair();
* }
*/
} else {
throw HDSException.exceptions
.invalidResponseFromHDS(String
.format("Not able to delete shadow image pair due to invalid response %1$s from server",
response.getStatus()));
}
} else {
log.info("Replication info is not available on pair management server");
}
} finally {
if (null != responseStream) {
try {
responseStream.close();
} catch (IOException e) {
log.warn("IOException occurred while closing the response stream");
}
}
}
return status;
}
public void refreshPairManagementServer(String pairMgmtServerHostObjId) throws Exception {
InputStream responseStream = null;
try {
if (pairMgmtServerHostObjId != null) {
log.info("Refreshing Pair Mgmt Server started");
Map<String, Object> attributeMap = new HashMap<String, Object>();
Add addOp = new Add(HDSConstants.HOST_REFRESH);
HDSHost host = new HDSHost();
host.setObjectID(pairMgmtServerHostObjId);
attributeMap.put(HDSConstants.ADD, addOp);
attributeMap.put(HDSConstants.HOST, host);
String refreshHostQuery = InputXMLGenerationClient.getInputXMLString(
HDSConstants.REFRESH_HOST_OP, attributeMap,
HDSConstants.HITACHI_INPUT_XML_CONTEXT_FILE,
HDSConstants.HITACHI_SMOOKS_CONFIG_FILE);
log.info("Query to refresh pair mgmt server: {}", refreshHostQuery);
URI endpointURI = hdsApiClient.getBaseURI();
ClientResponse response = hdsApiClient.post(endpointURI, refreshHostQuery);
if (HttpStatus.SC_OK == response.getStatus()) {
responseStream = response.getEntityInputStream();
JavaResult javaResult = SmooksUtil.getParsedXMLJavaResult(responseStream,
HDSConstants.HITACHI_SMOOKS_THINIMAGE_CONFIG_FILE);
verifyErrorPayload(javaResult);
log.info("Successfully refreshed pair mgmt server");
} else {
throw HDSException.exceptions
.invalidResponseFromHDS(String
.format("Not able to refresh pair mgmt server due to invalid response %1$s from server",
response.getStatus()));
}
} else {
log.info("Pair Mgmt Server Object id is null");
}
} finally {
if (null != responseStream) {
try {
responseStream.close();
} catch (IOException e) {
log.warn("IOException occurred while closing the response stream");
}
}
}
}
}