Comment

OK I think I have this working. I'll summarize my changes. All I did was the minimum necessary to accept reversed parameters, I do not account for mixed-order parameters as I don't think the OneFS API goes deep enough for me to get into trouble there yet. Below are the documented changes in case anyone else needs a quick fix for building an Isilon plugin. So far I've tested this for populating the plugin inventory, but I haven't tested adding methods, etc.

3 actions and 1 workflow were updated/duplicated and changed.

Actions:

  • validateUrl (duplicated and updated)
  • getUrlParamIds (duplicated and updated)
  • getParams (updated existing)

For the workflow, I duplicated Plugin gen -3- Create a type and called it Plugin gen -3b- Create a type with reversed parameterization.

Plugin gen -3b- Create a type with reversed parameterization:

I only needed to update presentation for Find Relation and Find By ID. For these sections I pointed to the duplicated validateUrl and getUrlParamIds

  1. For findRelationUrl -> Custom Validation - changed the 'Custom Validation' parameters for validateUrl.
    • Original parameters =  GetAction("com.vmware.coe.presentation","setValidation").call("validateFindRelationUrl",GetAction("com.vmware.coe.dynamicTypes.pluginGenerator.presentation","validateUrl").call( #findRelationUrl,#parentType))
    • New parameters = GetAction("com.vmware.coe.presentation","setValidation").call("validateFindRelationUrl",GetAction("com.advizex.dynamicTypes","validateUrl").call( #findRelationUrl,#parentType, null, true))
    • Additional parameter was added to validateUrl to indicate that parameters are being sent in reverse order
  2. Reversed the order of findRelationParam0-3 in presentation, pointed the 'predefined list of elements' to the duplicated getUrlParamIds, and changed the predefined list of elements call parameters to:
    • findRelationParam2 - #findRelationUrl !="" ? GetAction("com.advizex.dynamicTypes","getUrlParamIds").call( #parentType.namespace, #findRelationUrl, 3, null) : ""
    • findRelationParam1 - #findRelationUrl !="" ? GetAction("com.advizex.dynamicTypes","getUrlParamIds").call( #parentType.namespace, #findRelationUrl, 2, #findRelationParam2) : ""
    • findRelationParam0 - #findRelationUrl !="" ? GetAction("com.advizex.dynamicTypes","getUrlParamIds")..call( #parentType.namespace, #findRelationUrl, 1, #findRelationParam1)
    • This reversed the dependency of the parent to be right of the child in the parameter list
  3. For Find By ID -> Custom Validation - changed the 'Custom Validation' parameters for validateUrl.
    • Original parameters =  #findById ? GetAction("com.vmware.coe.presentation","setValidation").call("validateFindByIdUrl",GetAction("com.vmware.coe.dynamicTypes.pluginGenerator.presentation","validateUrl").call( #findByIdUrl,#parentType,#typeName )) : ""
    • New parameters = GetAction("com.vmware.coe.presentation","setValidation").call("validateFindRelationUrl",GetAction("com.advizex.dynamicTypes","validateUrl").call( #findRelationUrl,#parentType, null, true))
    • Additional parameter was added to validateUrl to indicate that parameters are being sent in reverse order
  4. Reversed the order of findRelationParam0-4 in presentation, pointed the 'predefined list of elements' to the duplicated getUrlParamIds, and changed the predefined list of elements call parameters to:
    • findByIdParam3 = #findById ? #findByIdUrl !=""  ? GetAction("com.advizex.dynamicTypes","getUrlParamIds").call( #parentType.namespace, #findByIdUrl, 4, null, #findRelationProperties) : "" : ""
    • findByIdParam2 = #findById ? #findByIdUrl !=""  ? GetAction("com.advizex.dynamicTypes","getUrlParamIds").call( #parentType.namespace, #findByIdUrl, 3, #findByIdParam3, #findRelationProperties) : "" : ""
    • findByIdParam1 = #findById ? #findByIdUrl !=""  ? GetAction("com.advizex.dynamicTypes","getUrlParamIds").call( #parentType.namespace, #findByIdUrl, 2, #findByIdParam2, #findRelationProperties) : "" :""
    • findByIdParam0 = #findById ? #findByIdUrl !=""  ? GetAction("com.advizex.dynamicTypes","getUrlParamIds").call( #parentType.namespace, #findByIdUrl, 1, #findByIdParam1, #findRelationProperties) : "" : ""
    • This reversed the dependency of the parent to be right of the child in the parameter list

In the following actions, changes are highlighted.

Duplicated validateUrl changes:

var debug = System.getModule("com.vmware.coe.dynamicTypes.pluginGenerator").getDebug();

var startDate = new Date();

if (url == null || url == "" || url == undefined) {

  if (debug == true) System.getModule("com.vmware.coe.tools").profile("validateUrl", startDate, "no URL");

  return "URL must be set";

}

var strings = url.split("/");

// The next 2 lines avoid errors for URL starting with / or finishing with /

if (strings[0].length == 0) strings[0]="a";

if (strings[strings.length -1].length == 0) strings[strings.length -1]="a";

for each (var string in strings) {

  // Test for in bracket {keyword}

  if (string.match(/[^{}]+(?=\})/g)) continue;

  // Test URL has valid content

  if (!string.match(/^[a-zA-Z0-9_.\-~=?&]*?$/)) {

  if (debug == true) System.getModule("com.vmware.coe.tools").profile("validateUrl", startDate, "Invalid character in URL");

  return "Invalid character in URL";

  }

}

//Check if parameters are all known types

var paramTypes = url.match(/[^{}]+(?=\})/g);

var namespace = parentType.namespace;

// No parameters

if (paramTypes == null || paramTypes.length ==0) {

  if (debug == true) System.getModule("com.vmware.coe.tools").profile("validateUrl", startDate, "Valid URL");

  return "";

}

//Got parameters

if (!isFirstTypeParent) isFirstTypeParent = false;    // new parameter to deal with reverse order

var firstTypeName = paramTypes[0];

var parentTypes = getParentTypes(namespace, firstTypeName, parentType, isFirstTypeParent).reverse();    // added to function

if (typeName != null) parentTypes.push(typeName);

parentTypes = parentTypes.reverse();    // reverses list to match parameters

var arrays = [parentTypes,paramTypes];

var intersect = System.getModule("com.vmware.coe.tools").intersectArrays(arrays);

var missing = arrayDiff(paramTypes, intersect);

//System.log("paramTypes : " + paramTypes);

//System.log("parentTypes : " + parentTypes);

//System.log("intersect : " + intersect);

if (missing.length >0) {

  if (debug == true) System.getModule("com.vmware.coe.tools").profile("validateUrl", startDate, "URL contain unknown type " + missing);

  return "URL contain unknown type " + missing;

}

if (JSON.stringify(intersect) !=JSON.stringify(paramTypes)) {

  if (debug == true) System.getModule("com.vmware.coe.tools").profile("validateUrl", startDate, "URL types in wrong order " + intersect);

  return "URL types in wrong order " + intersect;

}

if (debug == true) System.getModule("com.vmware.coe.tools").profile("validateUrl", startDate, "Valid URL");

return "";

function getParentTypes(namespace, firstTypeName, parentType, isFirstTypeParent) {

  var parentTypes = new Array();

  var currentTypeName = parentType.name;

  parentTypes.push(currentTypeName);

  while (true) {

  //System.log("+++++ currentTypeName : " + currentTypeName + " firstTypeName " + firstTypeName);

  //No need to get more parents if found one matching the first parameter type

  if (isFirstTypeParent == false) {

      if (currentTypeName == firstTypeName) {

      break;

  }    // deals with reversed order

  }

  // In case we get to the root level

  if (currentTypeName == namespace + "Host") {

  break;

  }

  currentTypeName = System.getModule("com.vmware.coe.dynamicTypes.pluginGenerator").getParentType(namespace, currentTypeName);

  parentTypes.push(currentTypeName);

  }

  return parentTypes;

}

function arrayDiff(array1,array2) {

  var diff = new Array();

  for (var i = array1.length - 1; i >= 0; i--) {

  var key = array1[i];

  if (-1 === array2.indexOf(key)) {

    diff.push(key);

  }

  }

  return diff;

}

Duplicated getUrlParamIds changes:

// This action has ugly scripting because sometimes I need to rush to get features with mixing various scripts. Sorry about that.

var debug = System.getModule("com.vmware.coe.dynamicTypes.pluginGenerator").getDebug();

if (debug == true) {

  System.log("**************************** getUrlParamIds " + url);

  var startDate = new Date();

}

if (namespace == null || url == null || paramNumber == null) {

  if (debug == true) System.log(System.getModule("com.vmware.coe.tools").profile("getUrlParamIds", startDate, url + " null"));

  return null;

}

var paramTypes = url.match(/[^{}]+(?=\})/g);

if (debug) System.log(paramTypes);

if (paramTypes == null || paramTypes.length < paramNumber) return null;

var type = paramTypes[paramNumber -1];

var firstType = paramTypes[0];    // original looks at lastType as the end, reverse and examine the first type

System.log("type : " + type);

System.log("firstType : " + firstType);

System.log("paramNumber : " + paramNumber);

// This is ugly but works a lot better then getting the URL for findRelation and getting name and Ids

if (type == firstType && propertiesPreview != null) {

  System.log("type == firstType");

  if (debug == true) System.getModule("com.vmware.coe.tools").profile("getUrlParamIds", startDate, url );

  System.log("******** GOT IDs from preview ********************\n");

  return getNameAndIdFromMutilineText(propertiesPreview);

}

if (parentId == null || parentId == "") {

  try {

  var objects = Server.findAllForType("DynamicTypes:" + namespace + "." + type);

  } catch(e) {System.warn(e)}

  System.log("******** GOT " + objects.length  + " objects using findAll ********************\n");

}

/*

if (parentId == null || parentId == "") {

  var objects = Server.findAllForType("DynamicTypes:" + namespace + "." + lastType);

  if (debug) System.log("Found " + objects.length + " " + lastType);

  var objectId = objects[0].id;

  var currentType = lastType;

  var ids = objectId.split("/");

  var idIndex = ids.length -1;

  while (currentType != type) {

  if (debug) System.log("currentType : " + currentType);

  var currentType = System.getModule("com.vmware.coe.dynamicTypes.pluginGenerator").getParentType(namespace, currentType);

  if (System.getModule("com.vmware.coe.dynamicTypes").isFolder(namespace, currentType) == false) idIndex--;

  }

  if (debug) System.log("Relations " + relations);

  var propIds = new Properties();

  for each (var object in objects) {

  var objectId = object.id;

  var id = objectId.split("/")[idIndex];

  var fullId = objectId.substring(0,objectId.indexOf(id) + id.length);

  propIds.put(fullId);

  }

  var objects = new Array();

  for each (var id in propIds.keys) {

  objects.push(Server.findForType("DynamicTypes:" + namespace + "." + type, id));

  }

  System.log("******** GOT IDs findAll ********************\n");

}*/

else {

  var currentType = type;

  var relations = new Array();

  var parents = new Array();

  if (paramTypes.length >1) var parentType = paramTypes[paramNumber];    // parentType is the next parameter to the right in the URL

  else var parentType = null;

  while (currentType != parentType) {

  var childType = currentType;

  var currentType = System.getModule("com.vmware.coe.dynamicTypes.pluginGenerator").getParentType(namespace, currentType);

  relations.push(currentType + "-" + childType);

  parents.push(currentType);

  }

  var objectId = parentId.split(" : ")[1];

  for (var i = relations.length - 1; i>=0; i--) {

  var relation = relations[i];

  var parentType = parents[i];

  //System.log("relation: " + relation);

  var objects = System.getModule("com.vmware.coe.dynamicTypes.pluginGenerator").findRelation(namespace + "." + parentType, objectId, relation);

  if (debug) System.log("Found " + objects.length + objects[0].type + " objects");

  parentId = objects[0].id;

  }

  System.log("******** GOT IDs findRelation ********************\n");

}

var array = new Array();

for each (var object in objects) {

  if (debug) System.log(object.name + " : " + object.id);

  array.push(object.name + " : " + object.id);

}

if (debug) System.log("Found " + array.length + " " + type + " id & name");

if (debug == true) System.getModule("com.vmware.coe.tools").profile("getUrlParamIds", startDate, url );

return array;

function getNameAndIdFromMutilineText(text) {

  var array = new Array();

  var textLines = text.split("\n");

  for each (var textLine in textLines) {

  if (textLine.indexOf(" : ") >-1) {

  var key = textLine.split(" : ")[0];

  var value =  textLine.split(" : ")[1];

  if (key == "id") {

  var id = value;

  continue;

  }

  if (key == "name") {

  array.push (value + " : " + id);

  continue;

  }

  }

  }

  return array;

}

getParams changes:

var debug = System.getModule("com.vmware.coe.dynamicTypes.pluginGenerator").getDebug();

if (debug == true) {

  System.log("**************************** getParams " + parentType);

  var startDate = new Date();

}

var namespace = parentType.split(".")[0];

var paramTypes = urlTemplate.match(/[^{}]+(?=\})/g);

if (paramTypes == null) return null;

var currentType = parentType.split(".")[1];

var parentOfParent = System.getModule("com.vmware.coe.dynamicTypes.pluginGenerator").getParentType(namespace, currentType);

if (parentOfParent == paramTypes[0]) {

  var isReverse = true;

  paramTypes.reverse();

} // if the first parameter is the parent of the type, we know the order is reversed

var param0Type = paramTypes[0];

var params = new Array();

var ids = parentId.split("/");

var idIndex = ids.length -1;

while (currentType != param0Type) {

  var currentType = System.getModule("com.vmware.coe.dynamicTypes.pluginGenerator").getParentType(namespace, currentType);

  for (var i = paramTypes.length - 1; i>=0; i--) {

  if (paramTypes[i] == currentType) {

  params.push(ids[idIndex]);

  if (debug) System.log("************************************************ " +  currentType + " : " + ids[idIndex]);

  idIndex--;

  break;

  }

  }

}

if (debug == true) System.getModule("com.vmware.coe.tools").profile("getParams", startDate, urlTemplate );

return isReverse ? params : params.reverse();    // if the order is not reversed, return as the original, otherwise return un-reversed params