Use Effort Calculator variables in a Forward Path scenario
This topic provides an introduction to the use of the Effort Calculator variables in your Forward Path scenario. This topic uses an example to introduce the use of these features.
About the Effort Calculator variables
Effort Calculator estimates the cost and effort involved in remediating your application portfolio for a target platform (represented by one of the AppDNA reports). The calculation uses two main types of variables:
- User-defined variables – These store values such as how much a tester, remediator, and project manager cost per day, the number of hours in a typical working day, how long it takes on average to remediate applications of different complexities (simple, normal, and complex), taking into account the difficulty of the remediation action (easy, medium, or hard). You can set these variables separately for each AppDNA report in the Effort Calculator screen.
- Application-level variables – These are derived from the AppDNA analysis and include the complexity of the application (this is based on the number of files and registry entries the application has), and the difficulty (or complexity) of the actions that need to be taken to remediate the application for the selected report.
Using this information Effort Calculator estimates the expected cost of migrating the entire application portfolio to the new platform. You can now use these variables in your Forward Path scenario – for example, to estimate the cost of remediating each application. This topic provides a relatively simple example of how to do this. One of the sample scenarios that comes with AppDNA provides a more complex and sophisticated example.
For detailed information about the Effort Calculator variables and how they are used, see Effort Calculator.
Retrieving the user-defined Effort Calculator variables
You can access the user-defined Effort Calculator variables through the EffortCalculatorSettings object, which you retrieve through the Host object. The Host object is implicitly available to the entire scenario script. Here is a snippet that retrieves the EffortCalculatorSettings object for the Windows 7 report:
``` pre codeblock Private Dim vars As EffortCalculatorSettings
’ Get the Windows 7 Effort Calculator settings object. vars = Host.GetEffortCalculatorSettings(“Win7Module”)
Notice that we have used the Windows 7 internal report identifier to retrieve the Effort Calculator variables for Windows 7. For a list of the report identifiers, see [Create links to remediation report views](/en-us/dna/current-release/configure/forward-path/dna-forward-path-remediation-links.html). You can see all of the properties of the EffortCalculatorSettings object in the Property Explorer on the right side of the [Forward Path Logic Editor screen](/en-us/dna/current-release/configure/forward-path/dna-forward-path-logic-editor.html). The names of the properties closely relate to the text shown for the variables in the Effort Calculator screen. For example, the AppStagingHours property corresponds to the Staging time variable in the Staffing variables section of the Effort Calculator screen. We will use this variable in the example that follows. It is possible to set the values of these variables in your scenario for use in that scenario, like this: ``` pre codeblock vars.TesterStagerCostPerDay = 23
Note: This does not change or overwrite the variables that Effort Calculator uses.
About the example
To illustrate how to use the two types of Effort Calculator variables to calculate the estimated costs of remediating applications in your Forward Path scenario, we will walk through an example scenario. We will build it up in stages, in an attempt to make it easy to understand.
Here is a screenshot of the output the example creates:
Note: The examples in this topic use the underscore (_) notation to break long lines into two or more lines. This is so that the example code snippets render correctly when included in a PDF. See the MSDN Library for more on this notation.
Initialize the variables
AppDNA includes a Forward Path scenario function called Initialize(). If present in the scenario, AppDNA automatically calls this at the start of the processing. We will use this to initialize variables that we will use later in the scenario. For more information about the Initialize() function, see Grouped Forward Path reports.
Before the Initialize() function, we declare some variables that we will use throughout the script.
``` pre codeblock ‘ Declare variables for use throughout the script. Private Dim vars As EffortCalculatorSettings Private Dim testingPerHour As Decimal = 0 Private Dim remediationPerHour As Decimal = 0
Here is the Initialize() function: ``` pre codeblock Public Overrides Sub Initialize() ' Get the Windows 7 Effort Calculator settings object. vars = Host.GetEffortCalculatorSettings("Win7Module") ' Calculate the testing and remediation cost per hour. testingPerHour = vars.TesterStagerCostPerDay / _ vars.NormalAppTestingHours remediationPerHour = vars.RemediatorCostPerDay / _ vars.NormalAppTestingHours ' Sort the report in descending order of cost. Settings.ApplicationSortBy = "Cost" Settings.ApplicationSortDescending = true End Sub
Notice that we are calculating the hourly testing and remediation costs. We do this by dividing the values stored in the variables that represent the tester or remediator cost per day by the value stored in the normal number of working hours in a day variable.
At the end of the Initialize() function, we set the sort order to be in descending order of the values in the Cost column. In this column we will display the calculated cost of remediating the application and staging it for UAT.
The main function
Here is the main ForwardPath() function. AppDNA automatically calls this once for every application that is selected when you run the report. Explanatory notes follow the example.
``` pre codeblock Public Function ForwardPath(ByVal currentApplication _ As Application) As Output
Dim result As New Output()
’ We will use three custom columns. result.CustomField1.Name = “Application Complexity” result.CustomField2.Name = “Action RAG” result.CustomField2.Value = _ currentApplication.Modules.Windows7.ActionRAG result.CustomField3.Name = “Action Complexity”
’ Set the culture on the Cost column to US English, ‘ so that the US dollar currency symbol is used. result.Display.Cost.Culture = “en-US”
’ Test the application’s main RAG status, because ‘ the remediation depends on this. Select Case currentApplication.Modules.Windows7.RAG
Case Rag.Green ' The RAG is green, so no remediation is necessary ' and the application can be staged for UAT. result.Outcome = "Stage UAT" result.RAG = RAG.Green ' No remediation is required, so the cost is of ' the staging only. result.Cost = testingPerHour * vars.AppStagingHours result.CustomField3.Value = "--" ' Convert the unfriendly application complexity ' "RAG" to a text. Select Case currentApplication.Complexity Case RAG.Red result.CustomField1.Value = "Complex" Case RAG.Amber result.CustomField1.Value = "Medium" Case RAG.Green result.CustomField1.Value = "Simple" End Select Case Rag.Amber ' The RAG is amber, so the application needs ' remediation. result.RAG = RAG.Amber result.Outcome = "Remediate" ' The cost calculation is more complicated, ' so we will do it in a separate "GetCost()" ' function. result.Cost = GetCost(currentApplication, result) Case Rag.Red ' The RAG is red - we need to check the action ' RAG to see if remdiation is possible. result.RAG = RAG.Red ' If the action RAG is red, the application ' cannot be remediated. If (currentApplication.Modules.Windows7.ActionRAG = _ RAG.Red) Then result.Outcome = "Redevelop" result.CustomField3.Value = "Hard" ' Convert the unfriendly application complexity ' "RAG" to a text and set an arbitrary ' replacement/redevelopment cost. Select Case currentApplication.Complexity Case RAG.Red result.CustomField1.Value = "Complex" result.Cost = 3000 Case RAG.Amber result.CustomField1.Value = "Medium" result.Cost = 2000 Case RAG.Green result.CustomField1.Value = "Simple" result.Cost = 1000 End Select ' The action RAG is not red, so remediation is ' possible. Else result.Outcome = "Remediate" result.Cost = GetCost(currentApplication, result) End If Case Else ' Catch all for applications that have not been ' analyzed or that are locked. result.Outcome = "Unknown" result.RAG = RAG.Unknown result.CustomField1.Value = "--" result.CustomField3.Value = "--" result.Cost = 0
result.Display.SourcePath.Visible = false
ForwardPath = result
Notice that this function starts by setting up three custom columns (called CustomFieldn) – these are the three right-most columns in the screenshot of the output above. We use these as follows: | Column | Displays | | ---| --- | | CustomField1 | The application complexity. Forward Path stores this as a red/amber/green "RAG". We translate these values into Complex/Medium/Simple texts in the script. | | CustomField2 | The application's action RAG. We get the value using the Application.Modules.Windows7.ActionRAG property.| | CustomField3 | The complexity/difficulty of the application's remediation action. We will retrieve the value for this column later in the script. | The Cost column is automatically displayed in currency format. By default, Forward Path uses the currency symbol for the regional settings on the user's computer. In an international environment, this means that the currency symbol may vary depending on the settings on the device of the person viewing the report. (For example, it might display the euro sign for a user in France, the UK pound sign for a user in England, and the US dollar sign for a user in the United States.) In this example, we will therefore specify the US dollar symbol so that this will always be displayed regardless of the user's regional settings. To do this, we set the Culture property on the Cost column to "en-US", which indicates the United States. The main body of the function consists of a Select Case statement that tests the application's Windows 7 RAG status and provides different processing depending on that status. Let's look at how we handle each value: - **Green RAG** – The application can go straight to UAC. So we calculate the cost of staging the application by multiplying the cost of testing per hour (which we calculated in Initialize()) by the Effort Calculator variable that stores the number of hours it takes to stage an application for testing. We set the action complexity to "--" because remediation is not necessary, and we use another Select Case statement to test the application's complexity and convert the unfriendly "RAG" value into a text. - **Amber RAG** – The application needs remediation. We call the GetCost() function to calculate the remediation cost. We will look at this shortly. - **Red RAG** – We first test the action RAG. If it is red, it means that the application cannot be remediated and needs to be redeveloped or replaced. We then use a Select Case statement to test the application complexity like we did for the green RAG. However, this time we set an arbitrary replacement cost based on the complexity of the application. For applications that can be remediated (that is, their action RAG is green or amber), we call the GetCost() function to calculate the remediation cost. - **Other RAG values** – We handle all other RAG values by using a Case Else statement. This will handle applications that have not been analyzed and those that are locked (unlicensed). ## Calculate the remediation cost Here is the GetCost() function, which we called in the main function to calculate the remediation costs of amber applications and red ones that can be remediated. Explanatory notes follow the example. ``` pre codeblock Private Function GetCost(app As Application, _ cols As Output) As Decimal Dim remediationCost As Decimal = 0 Dim testingCost As Decimal = 0 ' 1. Using the triggered algorithms, get the ' algorithm with the hardest action. We will use this ' in our calculations. Dim maxAlgorithm As TriggeredRule = _ (From r in app.TriggeredRules _ Where r.ModuleIdentifier = "Win7Module" _ Where r.Action.Complexity = ActionComplexity.Hard Or _ r.Action.Complexity = ActionComplexity.Medium Or _ r.Action.Complexity = ActionComplexity.Easy _ Order By r.Action.Complexity Descending _ Select r).FirstOrDefault() ' 2. Display the algorithm's action complexity. cols.CustomField3.Value = maxAlgorithm.Action.Complexity ' 3. The remediation cost depends on the application ' complexity. Select Case app.Complexity ' A complex application. Case RAG.Red cols.CustomField1.Value = "Complex" ' The remediation cost also depends on ' the complexity of the action. So we will ' calculate the time based on the number of ' hours held in the Effort Calculator matrix. Select Case maxAlgorithm.Action.Complexity Case ActionComplexity.Easy remediationCost = remediationPerHour * _ vars.ComplexAppEasyRemediationHours Case ActionComplexity.Medium remediationCost = remediationPerHour * _ vars.ComplexAppMediumRemediationHours Case ActionComplexity.Hard remediationCost = remediationPerHour * _ vars.ComplexAppHardRemediationHours Case Else remediationCost = remediationPerHour * _ vars.ComplexAppMediumRemediationHours End Select If app.Modules.Windows7.ActionRAG = RAG.Amber Then ' Add the additional post-remediation testing ' because the application has an amber action RAG. testingCost = testingPerHour * _ vars.ComplexAppTestingHours End If ' A medium-complexity application. Case RAG.Amber cols.CustomField1.Value = "Medium" Select Case maxAlgorithm.Action.Complexity Case ActionComplexity.Easy remediationCost = remediationPerHour * _ vars.NormalAppEasyRemediationHours Case ActionComplexity.Medium remediationCost = remediationPerHour * _ vars.NormalAppMediumRemediationHours Case ActionComplexity.Hard remediationCost = remediationPerHour * _ vars.NormalAppHardRemediationHours Case Else remediationCost = remediationPerHour * _ vars.NormalAppMediumRemediationHours End Select If app.Modules.Windows7.ActionRAG = RAG.Amber Then ' Add the additional post-remediation testing ' because the application has an amber action RAG. testingCost = testingPerHour * _ vars.NormalAppTestingHours End If ' A simple application. Case RAG.Green cols.CustomField1.Value = "Simple" Select Case maxAlgorithm.Action.Complexity Case ActionComplexity.Easy remediationCost = remediationPerHour * _ vars.SimpleAppEasyRemediationHours Case ActionComplexity.Medium remediationCost = remediationPerHour * _ vars.SimpleAppMediumRemediationHours Case ActionComplexity.Hard remediationCost = remediationPerHour * _ vars.SimpleAppHardRemediationHours Case Else remediationCost = remediationPerHour * _ vars.SimpleAppMediumRemediationHours End Select If app.Modules.Windows7.ActionRAG = RAG.Amber Then ' Add the additional post-remediation testing ' because the application has an amber action RAG. testingCost = testingPerHour * _ vars.SimpleAppTestingHours End If End Select ' 4. Add the remediation and testing costs, ' and the cost of staging for UAT. GetCost = remediationCost + testingCost + _ (testingPerHour * vars.AppStagingHours) End Function
The following notes relate to the numbers in the comments in the above example:
1. We use the current application’s Windows 7 TriggeredRules property. This property is a collection of TriggeredRule objects, which represent all of the algorithms that the application triggered during analysis for Windows 7. From this collection, we get the algorithm that has the hardest remediation action. We will use this to calculate the cost of remediating the application.
2. We display the complexity (difficulty) of the algorithm’s remediation action in CustomField3.
3. We then use a Select Case statement again to test the application’s complexity. We will provide different processing for each complexity. Let’s look at how we handle a complex application:
- First we use another Select Case statement to test the complexity (difficulty) of the action associated with the algorithm we retrieved in step 1. Then for each of the possible action complexities, we calculate the remediation cost by multiplying the remediation cost per hour (calculated in Initialize()) by the Effort Calculator variable that represents the time it takes to remediate a complex application of the corresponding action complexity.
- We then check whether the action RAG is amber – because this means that the application needs additional testing after the remediation has been implemented. If the action RAG is amber, we calculate the testing cost by multiplying the testing cost per hour (calculated in Initialize()) by the Effort Calculator variable that represents the time it takes to test a complex application.
The code for medium-complexity and simple applications mirrors the code for the complex application, but each time we select the Effort Calculator variables for medium and simple applications, respectively.
4. Finally, we add the remediation and testing costs we calculated to the cost of staging the application for UAT and set this into the return value.
For an example that calculates the remediation costs by taking into account the actions associated with all of the algorithms triggered by the application, see the sample scenario that comes with AppDNA.