Skip to content

Instantly share code, notes, and snippets.

@vmwarecode
Created June 27, 2016 20:51
Show Gist options
  • Select an option

  • Save vmwarecode/4544cb3ff6bba1d24f2471361d70ae17 to your computer and use it in GitHub Desktop.

Select an option

Save vmwarecode/4544cb3ff6bba1d24f2471361d70ae17 to your computer and use it in GitHub Desktop.
SDRSRecommendation
/*
* ****************************************************************************
* Copyright VMware, Inc. 2010-2016. All Rights Reserved.
* ****************************************************************************
*
* This software is made available for use under the terms of the BSD
* 3-Clause license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.vmware.storage;
import com.vmware.common.annotations.Action;
import com.vmware.common.annotations.Option;
import com.vmware.common.annotations.Sample;
import com.vmware.connection.ConnectedVimServiceBase;
import com.vmware.vim25.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* <pre>
* This sample demonstrates how to Run the Storage DRS on a given SDRS cluster and show
* the list of recommendations generated by SDRS.
* <b>Parameters</b>
*
* url [required]: url of the web service.
* userName [required]: username for the authentication.
* password [required]: password for the authentication.
* podame [required]: StoragePod name.
*
* <b>Sample Usage:</b>
* run.bat com.vmware.storage.SDRSRecommendation --url [URLString] --username [User]
* --password [Password] --podname [podname]
* </pre>
*/
@Sample(name = "sdrs-recommendation", description = "" +
"This sample demonstrates how to Run the Storage DRS on a given SDRS cluster and show\n" +
"the list of recommendations generated by SDRS.\n")
public class SDRSRecommendation extends ConnectedVimServiceBase {
private ManagedObjectReference propCollectorRef;
String podName;
@Option(name = "podname", description = "StoragePod name.")
public void setPodName(String name) {
this.podName = name;
}
List<ObjectContent> retrievePropertiesAllObjects(
List<PropertyFilterSpec> listpfs) throws RuntimeFaultFaultMsg, InvalidPropertyFaultMsg {
RetrieveOptions propObjectRetrieveOpts = new RetrieveOptions();
List<ObjectContent> listobjcontent = new ArrayList<ObjectContent>();
RetrieveResult rslts =
vimPort.retrievePropertiesEx(propCollectorRef, listpfs,
propObjectRetrieveOpts);
if (rslts != null && rslts.getObjects() != null
&& !rslts.getObjects().isEmpty()) {
listobjcontent.addAll(rslts.getObjects());
}
String token = null;
if (rslts != null && rslts.getToken() != null) {
token = rslts.getToken();
}
while (token != null && !token.isEmpty()) {
rslts =
vimPort.continueRetrievePropertiesEx(propCollectorRef, token);
token = null;
if (rslts != null) {
token = rslts.getToken();
if (rslts.getObjects() != null && !rslts.getObjects().isEmpty()) {
listobjcontent.addAll(rslts.getObjects());
}
}
}
return listobjcontent;
}
/**
* @return An array of SelectionSpec covering entities that provide
* performance statistics.
*/
SelectionSpec[] getStorageTraversalSpec() {
// create a traversal spec that start from root folder
SelectionSpec ssFolders = new SelectionSpec();
ssFolders.setName("visitFolders");
TraversalSpec datacenterSpec = new TraversalSpec();
datacenterSpec.setName("dcTodf");
datacenterSpec.setType("Datacenter");
datacenterSpec.setPath("datastoreFolder");
datacenterSpec.setSkip(Boolean.FALSE);
datacenterSpec.getSelectSet().add(ssFolders);
TraversalSpec visitFolder = new TraversalSpec();
visitFolder.setType("Folder");
visitFolder.setName("visitFolders");
visitFolder.setPath("childEntity");
visitFolder.setSkip(Boolean.FALSE);
List<SelectionSpec> ssSpecList = new ArrayList<SelectionSpec>();
ssSpecList.add(datacenterSpec);
ssSpecList.add(ssFolders);
visitFolder.getSelectSet().addAll(ssSpecList);
return (new SelectionSpec[]{visitFolder});
}
/**
* Getting the MOREF of the StoragePod.
*/
ManagedObjectReference getStoragePodByName(String entityName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
ManagedObjectReference retVal = null;
// Create Property Spec
PropertySpec propertySpec = new PropertySpec();
propertySpec.setAll(Boolean.FALSE);
propertySpec.setType("StoragePod");
propertySpec.getPathSet().add("name");
// Now create Object Spec
ObjectSpec objectSpec = new ObjectSpec();
objectSpec.setObj(rootRef);
objectSpec.setSkip(Boolean.TRUE);
objectSpec.getSelectSet().addAll(
Arrays.asList(getStorageTraversalSpec()));
// Create PropertyFilterSpec using the PropertySpec and ObjectPec
// created above.
PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec();
propertyFilterSpec.getPropSet().add(propertySpec);
propertyFilterSpec.getObjectSet().add(objectSpec);
List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>();
listpfs.add(propertyFilterSpec);
List<ObjectContent> listobjcont =
retrievePropertiesAllObjects(listpfs);
if (listobjcont != null) {
for (ObjectContent oc : listobjcont) {
if (oc.getPropSet().get(0).getVal().equals(entityName)) {
retVal = oc.getObj();
break;
}
}
}
return retVal;
}
/**
* Retrieve contents for a single object based on the property collector
* registered with the service.
*
* @param mobj Managed Object Reference to get contents for
* @param properties names of properties of object to retrieve
* @return retrieved object contents
*/
ObjectContent[] getObjectProperties(
ManagedObjectReference mobj, String[] properties) throws RuntimeFaultFaultMsg, InvalidPropertyFaultMsg {
if (mobj == null) {
return null;
}
PropertyFilterSpec spec = new PropertyFilterSpec();
spec.getPropSet().add(new PropertySpec());
if ((properties == null || properties.length == 0)) {
spec.getPropSet().get(0).setAll(Boolean.TRUE);
} else {
spec.getPropSet().get(0).setAll(Boolean.FALSE);
}
spec.getPropSet().get(0).setType(mobj.getType());
spec.getPropSet().get(0).getPathSet().addAll(Arrays.asList(properties));
spec.getObjectSet().add(new ObjectSpec());
spec.getObjectSet().get(0).setObj(mobj);
spec.getObjectSet().get(0).setSkip(Boolean.FALSE);
List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>(1);
listpfs.add(spec);
List<ObjectContent> listobcont = retrievePropertiesAllObjects(listpfs);
return listobcont.toArray(new ObjectContent[listobcont.size()]);
}
/**
* Retrieve a single object.
*
* @param mor Managed Object Reference to StoragePod.
* @return retrieved object
*/
Object getDynamicProperty(ManagedObjectReference mor) throws RuntimeFaultFaultMsg, InvalidPropertyFaultMsg, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
ObjectContent[] objContent =
getObjectProperties(mor, new String[]{"podStorageDrsEntry"});
Object propertyValue = null;
if (objContent != null) {
List<DynamicProperty> listdp = objContent[0].getPropSet();
if (listdp != null) {
/*
* Check the dynamic propery for ArrayOfXXX object
*/
Object dynamicPropertyVal = listdp.get(0).getVal();
String dynamicPropertyName =
dynamicPropertyVal.getClass().getName();
if (dynamicPropertyName.indexOf("ArrayOf") != -1) {
String methodName =
dynamicPropertyName.substring(
dynamicPropertyName.indexOf("ArrayOf")
+ "ArrayOf".length(),
dynamicPropertyName.length());
/*
* If object is ArrayOfXXX object, then get the xxx[] by invoking
* getXXX() on the object. For Ex:
* ArrayOfManagedObjectReference.getManagedObjectReference()
* returns ManagedObjectReference[] array.
*/
if (methodExists(dynamicPropertyVal, "get" + methodName, null)) {
methodName = "get" + methodName;
} else {
/*
* Construct methodName for ArrayOf primitive types Ex: For
* ArrayOfInt, methodName is get_int
*/
methodName = "get_" + methodName.toLowerCase();
}
Method getMorMethod =
dynamicPropertyVal.getClass().getDeclaredMethod(
methodName, (Class[]) null);
propertyValue =
getMorMethod.invoke(dynamicPropertyVal, (Object[]) null);
} else if (dynamicPropertyVal.getClass().isArray()) {
/*
* Handle the case of an unwrapped array being deserialized.
*/
propertyValue = dynamicPropertyVal;
} else {
propertyValue = dynamicPropertyVal;
}
}
}
return propertyValue;
}
/**
* Determines of a method 'methodName' exists for the Object 'obj'.
*
* @param obj The Object to check
* @param methodName The method name
* @param parameterTypes Array of Class objects for the parameter types
* @return true if the method exists, false otherwise
*/
@SuppressWarnings("rawtypes")
boolean methodExists(Object obj, String methodName,
Class[] parameterTypes) throws NoSuchMethodException {
boolean exists = false;
Method method = obj.getClass().getMethod(methodName, parameterTypes);
if (method != null) {
exists = true;
}
return exists;
}
/**
* Run the Storage DRS on a given SDRS cluster and show the list of
* recommendations generated by SDRS.
*
* @throws Exception
*/
void storageRecommendation() throws RuntimeFaultFaultMsg, InvalidPropertyFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
ManagedObjectReference srmRef =
serviceContent.getStorageResourceManager();
ManagedObjectReference sdrsMor = getStoragePodByName(podName);
if (sdrsMor != null) {
vimPort.refreshStorageDrsRecommendation(srmRef, sdrsMor);
System.out.println("\nSuccess: Refresh Cluster Recommendation.");
PodStorageDrsEntry podStorageDrsEntry =
(PodStorageDrsEntry) getDynamicProperty(sdrsMor);
List<ClusterRecommendation> clusterRecommendationList =
podStorageDrsEntry.getRecommendation();
if (!clusterRecommendationList.isEmpty()) {
System.out.println("\nList of recommendation: ");
for (ClusterRecommendation recommend : clusterRecommendationList) {
System.out.println(recommend.getType() + " Reason: "
+ recommend.getReason() + " target: "
+ recommend.getTarget().getValue());
}
} else {
System.out.println("\nNo Recommendations.");
}
} else {
throw new RuntimeException("Failure: StoragePod " + podName
+ " not found.");
}
}
@Action
public void run() throws RuntimeFaultFaultMsg, InvocationTargetException, InvalidPropertyFaultMsg, NoSuchMethodException, IllegalAccessException {
propCollectorRef = serviceContent.getPropertyCollector();
storageRecommendation();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment