Feeds:
Posts
Comments

Posts Tagged ‘Visual Studio Item Template’

The Problem:
System Center Orchestrator 2012 exposes a data service that enables to query and execute runbooks.  But working directly with the data service is like executing a WCF service by manually composing the SOAP messages. There are no type-safe parameters, no intellisense and you need to type the exact path of the runbook or even worse, specify GUIDs . Developing and testing a code that is involved with runbooks execution quickly becomes a cumbersome and tedious task.

The Solution:
The solutions is a Visual Studio item template.  When you add it to an existing project, it will ask for the Orchestrator server’s details and generate hierarchy of proxy classes that match-up with the Orchestrator server folders’ hierarchy, and within every class there will be methods that will match-up with the runbooks on said folder that accept the runbook’s parameters. In addition, the runbook’s description will be appended to the method’s remark summary, which makes the Visual Studio intellisense more helpful. Every class that contains runbooks also implements an interface named “I{ClassName}” that include these methods for easier testing. After adding this item to your project you will be able to execute a runbook as seen in the following code:

 OrchestratorReference orchestratorReference = new OrchestratorReference();
 Guid jobId = orchestratorReference.Development.Utils.WriteErrorLog(message, activity, runbook);

The OrchestratorReference object can be initialized with the credentials for accessing the Orchestrator web services.Ex:

 OrchestratorReference orchestratorReference = new OrchestratorReference();
 NetworkCredential cred = new NetworkCredential(userName, password, domain);
 orchestratorReference.OrchestratorServiceCredentials = cred;

In case the runbook path’s prefix depends on development environments you can use the “AddReplaceFolderPrefix” method to dynamically replace the path prefix. Ex:

 OrchestratorReference orchestratorReference = new OrchestratorReference();
 orchestratorReference.AddReplaceFolderPrefix(@"\Development\", @"\Production\");

All the runbooks’ functions return the job Id that was created on the Orchestrator server. The execution of the runbooks is asynchronized, to wait for the runbook completion and optionally collect the runbook’s return values, you can use the created job Id with the following methods:
Sync:

 Guid jobId = orchestratorReference.Development.VMManager.VM.GetNextVMName("Test##");
 Dictionary<string, string> result = orchestratorReference.GetJobResult(jobId);
 string nextVMName = result["nextVMName"];

Async:

 public async Task GetNextVMName(string template)
 {
   OrchestratorReference orchestratorReference = new OrchestratorReference();
   Guid jobId =
         orchestratorReference.Development.VMManager.VM.GetNextVMName(template);
   Dictionary<string, string> result =
                     await orchestratorReference.GetJobResultAsync(jobId);
   return result["nextVMName"];
 }

The T4 template, responsible for generating the code, removes any classes/methods duplication and will name classes/methods with Pascal-case and methods parameters with camel-case. It also removes from the class/methods’ name any un-letter prefix characters, so if the folder name includes an index number prefix, this index will be truncate and will be visible only from the class/methods remark’s summary.

Deployment:

  1. Extract the zip file available for download at the bottom of this post.
  2. Execute the “DeployItemTemplate.cmd” file.

Using:

  1. Open Visual Studio 2010.
  2. Click on add -> new item… in a project from which you need to execute a runbook
  3. Choose the “Orchestrator Reference” template from the template list, type in a file name and click OK.
    Orchestrator Reference - add item template
  4. Type the Orchestrator server’s name, port number where the Orchestrator service is listening (default 81) and if SSL is required.
  5. Click on the “Load” button. The wizard will load the folders structure from the Orchestrator service and will enable to specify which folders to include in the new generated class.
    Orchestrator Reference
  6. Click the “Add” button.
  7. Optional – Expand the template file to check the generated cs file.
  8. Happy developing!

Source & Binary

Read Full Post »

Alex Crome had recently published a good article about Creating a factory default widgets plugin. After trying to follow his process to develop some widgets for our community site I found a couple of issues with the proposed method:

  • Many repeating tasks. For each widget you need to:
    • Copy&paste the xml provided on the article.
    • Generate new GUID and set it in the xml file.
    • Create new folder using said GUID as the name, under the widgets’ folder.

    Though all Telligent’s out-of-the-box widgets follow the same standards, implementing them, will require some additional steps:

    • Creating configuration elements for the widget title and for the widget configuration. Using these configurations in the widget xml file.
    • Adding a ui.js file to the widget and using the registerEndOfPageHtml method to include this file with the widget.
    • Defining a property with the namespace of the project in the ui.js file and extending the JQuery object.
    • Defining a register function in the ui.js file and calling this function from the widget xml file providing the context object.
  • After creating a few widgets in one project it becomes more difficult to work with these GUID folders; updating the widget requires you to open the widget xml, check the widget’s GUID and look for a matching folder.
  • Deploying any changes to the widget files requires opening a browser on the site control panel and from the developer tools clicking the “Clear Cache” button.

Personally, I feel this method requires a lot to do before you even begin developing your widget…

So, being my old lazy self I started thinking of a way to reduce all the manual work described so far while enforcing best practice and ended up with 2 visual studio item templates to do the work for me.

After deploying the item templates, the process of developing widget in visual studio will look like this:

  1. Open a new Class Library project.
  2. Right click on the project name and open the project properties. Under Application tab set the Assembly name and the default namespace.
  3. Save the solution.
  4. Add reference to Telligent.Evolution.Components.dll and Telligent.Evolution.ScriptedContentFragments.dll.
  5. Right click on the project name and select add > new item. Choose the  “WidgetFactoryDefaultProvider” from the installed templates.WidgetFactoryDefaultProvider
  6. Give the default provider a name like [CompanyName]FactoryDefaultProvider.cs
  7. When you click on the Add button the following window will open
    factory dialog
  8. On the Deployment site URL box, enter the URL for the site you would like to automatically deploy the widgets to (do not include any page name like default.aspx as suffix).
  9. On the Deployment site root folder box, enter the root folder of the above site (the folder that contains the bin folder).
  10. If you would like that every time you deploy an update the deployment script will automatically delete all the content of the widget provider folder, leave the checkbox unchecked. Otherwise, existing files will remain on the folder and only files that exist in the project will be overwrite.
  11. Click the create button. The item template will do the following tasks automatically:
    1. Create DefaultWidget folder under the project root.
    2. Create a factory default widgets plug-in with a new GUID as the provider identifier.
    3. Copy an assembly to the site bin folder that enable clearing the cache.
    4. Copy a generic handler file to the utility folder to access the above assembly.
    5. Create the file WidgetDeploy.ps1, a PowerShell script based on the answer you provided for deploying the files to the Telligent site and clear the cache.
  1. Compile the project and copy the result assembly to the Bin folder of the deployment site or just add the new class library as a reference to the deployment site project.
  2. Enable the new provider from the “Manage plugins” page.
  3. To simplify the execute of the PowerShell script you can add an external tool in visual studio:
    1. In the Tools menu, choose External Tools.
    2. In the External Tools dialog box, choose Add, and enter a name for the menu option in the Title box like “Update widget’s files”.
    3. In the Command box, enter powershell.exe
    4. In the Arguments box, enter "& '$(ProjectDir)WidgetDeploy.ps1'"
    5. Click on the OK button. After you have added a tool to the Tools menu, you can easily launch the update widget files tool from the tool menu.

To add new widgets to the project:

  1. Under the default widget folder add new item and choose the Widget template.
  1. In the name box, enter the name of the widget and click Add.
  2. This will do the following tasks automatically:
    1. Create folder with the widget name.
    2. Create under this folder the widget xml file and ui.js file.
    3. The xml file and the ui.js contain all the necessary content as described above (new GUID, default configuration, namespace registration …)

The development process should follow these steps:

  1. Add/Edit a widget definition or its supplementary files.
  2. From the Tool menu click the “update widget files”.
  3. Review the change in the Telligent Evolution site.
  4. Repeat.

To deploy the item templates:

  1. Download this file  and extract the RAR file.
  2. Execute “DeployTemplates.cmd”
  3. Make sure that PowerShell is in the right version and defined to allow executing unsigned scripts:
    1. Execute “StartPowerShell.cmd”
    2. Type Get-Host and make sure the version is 2.
    3. Type Get-ExecutionPolicy.
    4. If the response is Restricted type the following command:
      Set-ExecutionPolicy RemoteSigned

The item templates source is also included in the RAR file.

Read Full Post »