Subscribe

Value manipulation question

Hi all,

I'm trying to build an add-LUN-to-a-volume workflow (with WFA 1.1.1) and am running into a coding issue when trying to resize the containing volume. In essence, I need to add an amount of space to the volume which is proportional to the size of a new volume and alter the autosize parameters as well. I've tried two approaches to this:

(The command being used is the certified "resize volume" command. I've found the volume and packed it into the "vol" array, and $lun_01_size is defined as a number between 1-1999):

version 1:

autosize_grow_mb --> vol.autosize_grow_mb + (int)($lun_01_size * 1024 * 1.01 / 0.8 / 5)

-and-

version 2:

autosize_grow_mb --> add(vol.autosize_grow_mb,($lun_01_size * 1024 * 1.01 / 0.8 / 5)) , where the add(a,b) function is defined as: def add(a,b) {(int)a + (int)b;}

The Problem: Both approaches are performing a string addition when the workflow is executed, however: 1000 + 1000 = 10001000 and not the 2000 that I need.

Has anyone figured out a means of performing integer math on an existing array value?

(Sorry if this has already been answered - I'm working at a customer site whose Internet filters disable almost all functionality of the communities site, including the ability to reasonably search for anything)

To answer my own question, the form add((int)vol.autosize_grow_mb,(int)($lun_00_size *1024 * 1.01 / 0.8 / 0.5)) works, with def add(a,b) {a+b;}

Re: Value manipulation question

So I have done this in the past and will paste the code examples for the functions that I used.  The examples are based around building or modifying a SAN application based on user inputs.  I put a lot of effort into developing a single workflow that can be used to create net-new or modify an existing deployment.  Due to this requirement, I needed a double duty function to provide the full details.  I will explain each piece in detail.

============================================

 

In the size portion of the FindChart, I added the following entry - detGrowthNeeded(exist_userDB_vol1,exist_userDB_vol1_Lun2,userDB_vol1,$userDB_vol1_Lun2_size,$rateOfChange)

The Variables indicate:

exist_userDB_vol1 = boolean (true/false) and is set to determine if the volume already exists

exist_userDB_vol1_Lun2 = boolean (true/false) and is set to determine if the Lun already exists in the volume

userDB_vol1 = This is the define for the Volume and is used as a Reference variable

$userDB_vol1_Lun2_size = New Lun size

$rateOfChange = Rate of change used to determine snapshot space required in the addition to space

The Function detGrowthNeeded is used to evaluate the values being passed.  Specifically, this workflow gave the option to add multiple Luns after the fact and therefore, I didn't want to mistakenly resize a Volume if not required.  Based on the first two parameters passed, a second function (setNewVolSize) was called to execute the sizing changes:

--------------------------------------------

def detGrowthNeeded(createVolume,createLun,jctPoint,newLunSize,pctOfChange) {

     if (createVolume=='false') {

       if (createLun=='false') return (int)setNewVolSize(jctPoint,'',pctOfChange);

       else return (int) setNewVolSize(jctPoint,newLunSize,pctOfChange);

     }

     else {

       return (int) setNewVolSize(jctPoint,newLunSize,pctOfChange);

     }

}

--------------------------------------------

I used the Function setNewVolSize to actually do all of the calculations.  I could have placed this into a single function with the previous, but I wanted modularize the process to allow for easier use of code.  This is likely the piece you are most in need of.  Notice that I declare the value as an Integer (int).

--------------------------------------------

def setNewVolSize(growVolume, addSize, rateOfChange) {

      if (addSize=='')

          return (int)(growVolume.size_mb);

       else

          return (int)(growVolume.size_mb + (convertToGB(addSize) * (1.1+(rateOfChange/100))));

}

--------------------------------------------

Because I only wanted to provide sizes in Gigabytes, I created a third function (convertToGB) which is as it's name implies

--------------------------------------------

def convertToGB(size) {

     return (int)(size *1024);

}

--------------------------------------------

============================================

This approach can be modified to meet your customer's needs and likely you can just use setNewVolSize and convertToGB functions in your workflow without using the detGrowthNeeded function.  I hope this helps.  If you run into any snags let me know.  I haven't used this one in a while (1.0.2) so if there are any syntax issues, then let me know and I will make changes.  I did restore my old backup into 1.1.1 and ran a quick preview.  It looks like everything added up correctly.

Jeremy Goodrum, NetApp

The Pirate

Re: Value manipulation question

A question:

Why not use a function for the calculation?

def increment_to_vol (lun_size)

{

return ((int)(lun_size * 1024 * 1.01 / 0.8 / 5);

}

Since you put that value into a new volume variable you can set new_vol.autosize_grow_mb

to "vol.autosize_grow_mb + increment_to_vol($Lun_Size)"

Yaron

Re: Value manipulation question

Hi Goodrum,

pretty cool stuff... :-)

As to why I didn't use a function: I tend to do simple arithmetic out in the open and logic within functions.

But to the hart of my original posting:

It appears that there is a difference to how MVEL or WFA treats the values of the variables, depending on if they are in a function or used directly in the workflow.

For example,

add((int)vol.autosize_grow_mb,(int)($lun_00_size *1024 * 1.01 / 0.8 / 0.5))

def add(a,b) {a+b;}

adds two integers together, while

(int)vol.autosize_grow_mb + (int)($lun_00_size *1024 * 1.01 / 0.8 / 0.5))

catenates the two string values of the variables. The essence of my question is why does the type casting work when the variable is passed to a subroutine, but not work when the variable is directly cast (actually, it does work as (int)($i)+(int)($j), but I run into problems with arrays like (int)(volume1.size_mb)+(int)(volume2.size_mb). It seems almost as if the addition operator has precendence over the casting operator in MVEL, which would surprise me... so I was wondering if anyone could clue me in as to what is really going on above.