Dynamic Types plug-in generator package

Dynamic Types plug-in generator package

The plug-in generator package is a set of wizard and template workflows allowing to create a plug-in without doing any scripting.

Read more about Dynamic Types in this article.

To familiarize yourself with creating a Dynamic Types plug-in V2 you can follow this tutorial and/or this tutorial.

Requires:

Download the plug-in generator version 2 from sample exchange (Since November 2, 2016 since the package was moved from Flowgrab)

Handle REST APIs with JSON or XML message formats.

  • - Wizard based workflow to create a plug-in inventory handling
    • Multiple hosts *
    • Multiple levels of objects *
    • Caching to avoid repeating requests *
    • Requires a single URL per object to implement findRelation, findAll, findById *
    • Get object properties using
      • Simple properties: JavaScript like doted syntax
      • Complex properties: JSONSelect (By Lloyd Hilaiel) *
      • Complex properties with high performance: pluggable actions
  • - Wizard based workflow to create and invoke object methods that are wrappable into plug-in workflows *
  • - Export plug-in to a end user installable package including runtime

* New functionality of version 2

Special thanks to Brandon Saxe for integrating JSONSelect in Orchestrator.

Disclaimer: These samples workflows are provided AS IS and are not considered production quality and are not officially supported. Use at your own risk.

Attachments
Comments

Updated to reflect changes in DynamicTypes plug-in build 166032.

Updated the v2 package to fix cache, deserialization, presentation bugs.

Would you consider posting these on flow grab? It would make versioning, sharing, branching and downloading much easier.

It is done.

Since V2 is still under active development it is now linked on flowgrab.com

Is it typical that presentation of the plugin is working very, very slow? Sometimes I've to wait several minutes to be able to type anything inside of the text box.

In v1 we were able to select the action that executed the relation URLs. Is this available in v2? For instance with Veeam its required that i first post to /sessionmngr before i can execute anything else in the Rest API. In v1 i was able so simply copy the default execute action and add in an extra line for that POST and call my custom execute action without modifying the base execute action that comes with the package.

On my system it ranges from 20 to 30 seconds. If you run on shared demo environments I have seen up to 2 min 30 seconds.

The issue is related to the way vCO client handle dependencies of input fields that are set based on other fields.

Using a custom action is not yet available. I realize some REST APIs require to do custom requests so I will add a way to override the default action with a custom action for a given rest host.

I'm attempting to configure the Find By ID object. In the URL field I am entering /jobs/{ID} which will return the object with the matching ID. This displays the correct content in the Response field in the workflow presentation but it throws an error stating, "[findById URL], URL contain unknown type id". Again everything appears to be working correctly, I can click next and move on with the accessors which also are all displayed properly, but because its throwing the error i cannot submit the workflow. I've read through the tutorial linked above but it skips the Find All and Find By ID sections. Before i go messing with the presentation validation is this what i'm supposed to be doing in this section?

FWIW, I went through this same process with the same configs in v1 with no issues.

Try /jobs/{job} (or replace job with the name of your type name)

/jobs/{job} which is the name of my type, worked fine.

I have uploaded a new version of the V2 package allowing to associate a custom action with a REST with the "Set a custom request action for a host" workflow. This should address custom headers / custom requests requirements.

After upgrading from .17 to .18 Plugin gen -1- Install plug-in reports 5 validation errors.

Install plug-in references 5 resource elements that are deleted once you run it.

These validation errors should go away once you follow the process to install a plug-in : Install a DT plug-in package. You can try with the NSX one.

Maybe I should empty the content of the resource element instead of deleting them to avoid this.

Im not sure im doing this right but heres what ive tried... I looked throguh your script and found the action that appears to execute my API calls "com.vmware.coe.dynamicTypes.pluginGenerator.presentation.executeRequestJsonText" and cloned it to a new action where i added my custom API session calls. I ran the workflow "Set a custom action for a host" and selected the only rest host i have, which was created by the workflow "Plugin gen -2- Add new host", and selected my cloned action. If i look at the custom properties of the rest host i see the custom property "customRequestAction" and its set to the value of my cloned action. When i run "Plugin get -3- Create a type" when on the find relation page i get a 401 HTTP response stating that the session is not valid which is the result of not including the session header that i added in my cloned action. If i add the custom API session call directly to "...executeRequestJsonText" and run "...Create a type" i get the expected response. It appears that the create a type workflow is not picking up the custom property on my rest host that defines my custom execution action.

The only action that execute requests is executeRequestJson (executeRequestJsonText use it as well).

I added this in the action:

var customRequestAction = Server.getCustomProperty(restHost, "customRequestAction");

if (customRequestAction != null) {

  eval('var objectsProperties = System.getModule("' + customRequestAction.module.name + '").' + customRequestAction.name + "(restHost, method, url, params, content, contentType);");

  return objectsProperties;

}

Which gets the custom property value and execute the action.

With duplicating executeRequestjson (and removing thee lines to avoid infinite loop), adding a throw "stop" at the start I cannot run a single query on the host including the ones during Create a type workflow.

Please double check that the action is not executed adding a throw and double check if you have the lines I pasted in your executeRequestJson

It looks like while i was working with v1 i modified the executeRequestJson action to test out adding my custom headers and it automatically added a new version. When i tried to import yours from v2 .18 it was not imported because a newer version existed. I removed the action and re-imported it and I now see the additional code. I was able to copy the action, comment out those 5 lines, and add my custom header in the action and its running as expected now. Thanks!

I'm building out a dynamic type for an object that has selectors that are valid "null" values. When i try to configure the object through your package it throws an error "[Properties selectors}, Issue with accessor for properties ..." All the properties it displays the error for have a value of null, which again is what i expect depending on how the object was configured. Is it possible to have a null value be OK? perhaps just a warning not an error? I need to have those values represented as null if they are null and as their populated value if they're populated.

Edit the validatePropertiesAccessors action

You can comment these lines:

if (properties.keys.length >0) {

    if (debug == true) System.getModule("com.vmware.coe.tools").profile("validatePropertiesAccessors", startDate, "Issue with accessor for properties " + properties.keys);

    return "Issue with accessor for properties " + properties.keys;

}

I may comment these in a next release. The thing is this helps to find out invalid properties. It a property always return null then maybe there is a problem with it.

i can certainly comment it out myself but that functionality may break when you release your next version if i grab it so id prefer not to do that if possible. I understand it adds valuable feedback to the validity of the properties returned by the accessor which is why i thought perhaps a warning that the user could ignore may work well here instead of an error that prevents me from submitting the workflow.

This is a fair point. Your change will not be overwritten if I do not upgrade the version in next release or if you upgrade your version (but then you may loose the benefit of a next update). With that said this action is not a core component, it is just used by the create workflow to validate the properties.

I should have mentioned it but a presentation validation accept only 2 states : an error string and when it does not validate and "" when it does validate so I cannot display a warning.

Maybe I should just drop testing null properties - if someone get some he will still be able to run the update type workflow to remove a useless property.

How do deal with requests that will page results? For example when dealing with vShield Edge query all VXLAN virtual wires.

You can create 2 objects : the page one returning the pages and a child object returning the objects for a given page.

or you can return a single set of objects with making sure you can set the page to a very high number of object per page in your request

Is it possible to modify findRelation URL after creating an object?

Yes with the update operation workflow. Get the latest build if you downloaded yours a long time ago.

Are there any particular known issues with the most recently posted version running on vRO 6.0.1? Been struggling to get this to even get into defining the host past step 1, and it seems to be due to some issue crossing between the custom plug-in generator and the library itself (unless it's just me). It appears to generate the new namespace, but then fail when attempting to launch into defining the host/type. If there are no expected issues, I can post elsewhere to seek help so as not to derail the thread. Thanks,

I did not test on vRO 6 yet.

I will need more details on the error you got to find out what is going wrong.

Also do you use v1 or v2 ? I may retire v1 soon since v2 has a lot more functionality and close to all v1 functionality.

Hey,

Attempting to use v2 - can't seem to get v1 loaded into vRO6 to compare. Basically when attempting to run Plugin gen -1- Create new plug-in workflow, it fails inside of the vRO client without any fanfare. Inside of vSphere web client, the following notification is logged: "TypeError: Cannot call method "getResourceElementCategory" of null (Workflow:Define Type / Define Type (item4)#7)" A Dynamic Type with no properties gets created inside of the Inventory. I may need to setup a different environment with just 5.5 to compare and make sure it isn't user error, but let me know what you think. Thanks,

This is because you did not set the second input of this workflow (an icon for the host) and because I forgot to make this field mandatory.

ah yes, exactly it. I should've caught that. Will keep going from here Smiley Happy

I'm curious if I'm doing something wrong. For the findRelation URL, do you support multiple parameters both containing different types?

For example, building an Isilon plugin, the relationships work as follows:

The host contains access zones. Access zones contain SMB shares. SMB shares contain permissions. I have the relationships set up as follows via the plugin generator:

IsilonHost (root object)

     accessZoneFolder

          accessZone (GET /platform/1/zones)

               smbShareFolder

                    smbShare (GET /platform/1/protocols/smb/shares?zone={accessZone}

This works great. However I'm having trouble when trying to create permissions. The permissions object is actually returned as part of the share so the properties of a share in the plugin is a raw JSON string containing the permissions. I'm right clicking "smbShare" and selecting the option to create a new type. In order to create a relationship for permissions for each share, the findRelation URL would need to look like the following:

/platform/1/protocols/smb/shares/{smbShare}?zone={accessZone}

It appears that the plugin examines the first parameters OK but then I get an error in presentation:

2 errors - [findRelation URL], URL contain unknown type accessZone

If I remove the {smbShare} parameter, it finds accessZone and I get no errors, but this will not work since I need the share name in the URL. Likewise if I remove the {accessZone} parameter it works, however it only works for the default zone since I am unable to add that query parameter. Looking at your action for findRelation, it appears it only accepts one parameter for parent type and parent ID and what I'm doing will not work.


Can you confirm this? Do you have any suggestions for working around this issue? I love the plugin generator and I'm trying to stick with it but it may be difficult for this task if the current version will not provide a mechanism for passing multiple URL parameters.


EDIT: it appears if I reverse the order the workflow stops complaining but that blows up my response. So it looks like you can use multiple parameters and multiple types provided that a parent object comes first in the URL and a child comes second. In my case:  /platform/1/protocols/smb/shares/{accessZone}?zone={smbShare} allows the workflow to update parameter dropdowns effectively but functionality this will not work. Wondering if reversing this would be an issue?

The issue is that I am checking that the parameters are in the same order as the object hierarchy and certainly replacing these in order.

It is the first time I have your use case and I need to update the package to allow different orders and replace out of order as well.

I will try to look into this as soon as I find some time this week.

How would i get an existing dynamic object via a script? I see my dynamic objects and can select them but im not able to create a workflow to create a new object with the output of the workflow being the new dynamic object as its dynamic object type. I can create the type but i don't see how i can get the dynamic object programatically. Am I missing something?

For example i have a vRA ASD Service Blueprint that calls a vRO workflow that builds a Veeam job via Powershell (it cant be done through REST). After the job completes i filter through the Server.findAllForType Objects to find one that matches the name of my newly created job (powershell doesn't properly return the ID of the new job). I grab the job ID from that but then im stuck. I cant figure out how to use that ID to grab the actual DynamicTypes:Veeam.job type to return to vRA to be provisioned as a vRA Item.

I started digging through your code and I think I have it solved. In summary, I'm changing the actions validateUrl and getUrlParamIds to account for the reverse ordering. I'm also changing the workflow presentation to reverse the order as well to account for child to parent moving from left to right vs. right to left.

I'll post a summary of what I changed as soon as I get it working and if anything obvious sticks out as a possible concern you will likely know right away.

Thanks!

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

I am impressed you could dig up my messy code to change it to do what you expect.

Also Friday I released an updated version of the package that allows to enter URL parameters not in the same order as the object hierarchy and process it in findRelation / findByID,

I did not announce it since I was not able to fully test this use case. If you can confirm if this work that would be great.

You are close. To find an object by ID you need to use Server.FindForType(typeName, typeID);

Typename being the Dynamic Type name as the one displayed in the inventory and ID being being the id property value as shown in the inventory.

The id is in he form restServerId + "/" objectLevel1Id .... + objectLevelnId

I actually tried that buy it returns an "Object" type. How do i turn that into my dynamic object type:

If your scriptable task output attribute is of the type you are requesting it should set it.

Thanks, ill open a support ticket.

Just an FYI, upgrading from vRO 5.5 to 6 caused all my dynamic types to break. I'm going to work through getting them back up.

I am curious to know what broke and what is the cause of it. Unfortunately I am still covering vCO 5.X ATM so I did not have much time to work with 6

The Dynamic Types under the Namspace are all gone. My workflows that used the dynamic types now report "Dynamic type not found". When i try to add a new input or attribute my dynamic types are not shown as options.

Did you get this working in vRO 6.0.1? When i try to run "Plugin gen -3- Create a type" i get the error "java.lang.reflect.InvocationTargetException-->null during the "Processing presentation" phase.

I've removed my Veeam Dynamic Type and am rebuilding it, but i left my Isilon Dynamic Type, you can use that to troubleshoot if you want.

I was not aware this could happen. You should definitely open an SR for this one. DT definitions are stored as a resource element in the vCO DB. It is odd these are not reloaded on vRO 6

Sorry, perhaps i was just impatient. I ran it again and i didn't get this error.

I think I have got this error in the past (on 5.5.1) and was gone as soon as I tried again

Version history
Revision #:
1 of 1
Last update:
‎04-16-2014 03:42 AM
Updated by: