Friday, June 6, 2014

Reusing SLA Dashboard in Your Management Pack

Hope

Operations Manager 2012 contains variety of dashboards and widgets which could be reused if the one doesn't want to mess up with widgets development.
So was I, monitoring distributed application which supposed to have Service Level Agreement.
I've picked SLA Dashboard.

It can be created with the wizard:


On this page you have to pick SLAs to be represented on the dashboard:

 
... and after completing all steps you get this nice layout:


I've exported Management Pack containing dashboard and after taking a look at Component code I've noticed the binding of some GUID to ServiceLevel property of the dashboard:
<Binding PropertyId="ServiceLevel">
  <ComplexValueCollection Type="mpschema://Microsoft.EnterpriseManagement.Configuration.ManagementPackConfigurationGroup[]">
    <ComplexValue Type="mpschema://Microsoft.EnterpriseManagement.Configuration.ManagementPackConfigurationGroup">
      <Binding PropertyId="Id">
        <SimpleValue Type="xsd://string" Value="50898fd4-9c74-1c1c-257f-d435d1ef13af" />
      </Binding>
    </ComplexValue>
  </ComplexValueCollection>
</Binding>

 This GUID is an identifier of Configuration Group containing Service Level Objectives. This group is actually Service Level Tracking which you create through wizard in Authoring:
<ConfigurationGroups>
  <ConfigurationGroup ID="KI.Test.SLA.ConfigurationGroup" Accessibility="Public" Target="KI.Test.DistributedApplication" />
</ConfigurationGroups>


Hope is Gone

But you can't hardcode GUID in you custom Management Pack cause this value will be different in every environment. In is case it is common to replace the hardcoded GUID with reference to a property of Management Pack object.
So did I:
<Binding PropertyId="ServiceLevel">
  <ComplexValueCollection Type="mpschema://Microsoft.EnterpriseManagement.Configuration.ManagementPackConfigurationGroup[]">
    <ComplexValue Type="mpschema://Microsoft.EnterpriseManagement.Configuration.ManagementPackConfigurationGroup">
      <Binding PropertyId="Id">
        <Reference>$MPReference/KI.Test.DA!KI.Test.SLA.ConfigurationGroup/Id$</Reference>
      </Binding>
    </ComplexValue>
  </ComplexValueCollection>
</Binding>

KI.Test.DA is an ID of my Management Pack, KI.Test.SLA.ConfigurationGroup is ID of SLA Configuration Group and Id is a property name which I want to be put into list of Service Levels represented on dashboard.
I didn't expect any problem here however...
I got this:



The reference was null or the property was null or empty... I've tried all possible properties and found out that I can get access to KI.Test.DA!KI.Test.SLA.ConfigurationGroup/DisplayName. But property ID was just empty. I've managed to get ID property of any other class like System.Group and others but not Configuration Group. It is obviously a bug.
Checked this on SP1 and R2.

Other Way

So it became obvious that I need to get GUID of Configuration Group some other way.
I definitely can do it using SDK. And I need to put it into some variable and reference it in this binding instead of KI.Test.DA!KI.Test.SLA.ConfigurationGroup/Id.

Basically solution is:
1. Create Data Provider which gets Configuration Group name as an input and returns GUID as string.
2. Create queries for WPF and Silverlight Consoles
3. Extend SLA Dashboard with Data Provider
4. Define new variable in SLA Dashboard
5. Map output to this variable
6. Reference this variable in Service Level list

Pretty serious workaround, ha?

So by the end I have three DLLs wrapped into Management Pack:
1) Data Provider (server-side)
2) Query for WPF (desktop console)
3) Query for Silverlight (web console)

... all this bustle because SCOM doesn't handle Configuration Groups properly.

The code samples below.

Retrieving Configuration Group Id from SDK

var critString = string.Format(
    CultureInfo.CurrentUICulture,
    "[Name] = '{0}'",
    configGroupName);

var crit = new ManagementPackConfigurationGroupCriteria(critString);
var configGroups = Connection.ServiceLevelAgreements.GetConfigurationGroups(crit);
var configGroupId = string.Empty;
foreach (var cg in configGroups)
{ configGroupId = cg.Id.ToString();
}

Extending SLA Dashboard with Data Provider

<Variable Id="ConfigGroupId" Type="xsd://string" />
<Base>
  <Binding PropertyId="ServiceLevel">
    <ComplexValueCollection Type="mpschema://Microsoft.EnterpriseManagement.Configuration.ManagementPackConfigurationGroup[]">
      <ComplexValue Type="mpschema://Microsoft.EnterpriseManagement.Configuration.ManagementPackConfigurationGroup">
        <Binding PropertyId="Id">
          <Reference>$Variable/ConfigGroupId$</Reference>
        </Binding>
      </ComplexValue>
    </ComplexValueCollection>
  </Binding>
  <Binding PropertyId="Objects">
    <Component TypeId="KI.Test.Queries.GetSlaConfigGroupIdQuery">
      <Binding PropertyId="ConfigurationGroupName">
        <SimpleValue Type="xsd://string" Value="KI.Test.SLT.ServiceHealth.ConfigurationGroup" />
      </Binding>
      <Binding PropertyId="ConfigurationGroupId">
        <Reference>$Variable/ConfigGroupId$</Reference>
      </Binding>
    </Component>
  </Binding>
</Base>
 


 
 
 
 

No comments:

Post a Comment