locked
Discovery Strategies for Distributed Applications RRS feed

  • Question

  • Hi,

     I'm reviewing OpsManJam example MP, Demo.StoreApp. I'm looking for a better understanding as to what is really going on with the discoveries.

     Here's what I'm reading:

    1. <DiscoveryType><DiscoveryClass> based on Microsoft.Windows.ComputerRole (CompRole)
      DataSource is a light weight regkey filter
      Target is Microsoft.Windows.[Client | Server].OperatingSystem
    2. <DiscoveryType><DiscoveryClass> based on System.ApplicationComponent (AppComp)
      <DiscoveryRelationship> based on System.Containment between source=AppComp & target=CompRole
      DataSource is a script
      <ScriptBody> Create Instance of AppComp, Create Instance of CompRole, Create Instance of Relationship, Return
      Target is Step #1

    My question is: Is the ComputerRole being discovered twice?

    I understand that you need to provide the relationhip instance with both classes. Is the <DiscoveryType><DiscoveryClass> the way OpsMgr validates the return XML... and by that, ignoring the second discovery? Or is this a Ref count thing? Does this mean that the Seed discovery must be based on the same class as the second teirs of discoveries?

    Thanks

    Tuesday, September 28, 2010 4:27 PM

Answers

  • So yes.  The pattern you are showing, assuming your probe is in a discovery that targets the class your registry key is discovering, is called "picture painter" (which differes from seed pattern by not being able to have the seed host the computer role or windows application derivative).

    The script needs to use WMI to check for the same registry key, and if it is not present, it must return a blank payload.  This will allow the MP to successfully undiscover the app if the app is uninstalled (or the computer is unmarked).

    The script should also discover the seed again so that it does not get deleted - if the target of your script base discovery disappears, in your case, the seed?, then the script will not run again and your monitoring will not cease should you uninstall.


    Microsoft Corporation
    • Marked as answer by _Jason_ Friday, October 1, 2010 8:05 PM
    Friday, October 1, 2010 6:10 PM

All replies

  • Would have to see the script.  Unless the comprole instance is added to the discovery payload, it is only needed for completing the relationship reference.  If it is added twice, it will cause reference counting, but undelete could then be an issue.  Since the ref-count is increased if the two instances have the same key value, the second discovery would run again if the registry key were removed (because instance is not deleted util ref count is zero).  The script would need the logic to know when to undiscover.  Undiscovery with contains relationships is tricky, which is why we promote the seed pattern. 

    If the second instance is linked by hosting, it should NOT increase the ref count and it does not have to call createrelationship instance since just adding parent key properites will automatically create the hosting relationship.


    Microsoft Corporation
    • Proposed as answer by Nicholas Li Thursday, September 30, 2010 9:55 AM
    Thursday, September 30, 2010 1:25 AM
  • Yeah, The Seed discovery is a simple filtered registry discovery, so I'll just clip the top part...

       <Discovery ID="Demo.StoreApp.Discovery.StoreServer" Enabled="true" Target="Windows!Microsoft.Windows.Server.OperatingSystem" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>Discovery</Category>
        <DiscoveryTypes>
         <DiscoveryClass TypeID="Demo.StoreApp.ComputerRole.StoreServer" />
        </DiscoveryTypes>
        <DataSource ID="DS" TypeID="Windows!Microsoft.Windows.FilteredRegistryDiscoveryProvider">

    The in-depth discovery just calls a module, so I'll skip that and just show the module.

       <DataSourceModuleType ID="Demo.StoreApp.DataSource.DiscoverStore" Accessibility="Internal" Batching="false">
        <Configuration>
         <xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" />
         <xsd:element minOccurs="1" name="ComputerName" type="xsd:string" />
         <xsd:element minOccurs="1" name="StoreCode" type="xsd:string" />
         <xsd:element minOccurs="1" name="ServerOrClient" type="xsd:string" />
         <xsd:element minOccurs="1" name="Debug" type="xsd:boolean" />
        </Configuration>
        <OverrideableParameters>
         <OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int" />
         <OverrideableParameter ID="Debug" Selector="$Config/Debug$" ParameterType="bool" />
        </OverrideableParameters>
        <ModuleImplementation Isolation="Any">
         <Composite>
          <MemberModules>
           <DataSource ID="Script" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">
            <IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
            <SyncTime />
            <ScriptName>DiscoverStoreRelationships.vbs</ScriptName>
            <Arguments>$MPElement$ $Target/Id$ $Config/ComputerName$ $Config/StoreCode$ $Config/ServerOrClient$ $Config/Debug$</Arguments>
            <ScriptBody><![CDATA[
    
    '==================================================================================
    ' Script: 	DiscoverStore.vbs
    ' Date:		4/27/09	
    ' Author: 	Brian Wren, Microsoft Consulting Services
    ' Purpose:	Discovers Store class and relationship with Store Server and Client Servers for StoreApp sample application
    '==================================================================================
    
    'Constants used for event logging
    SetLocale("en-us")
    Const SCRIPT_NAME					= "DiscoverStore.vbs"
    Const EVENT_LEVEL_ERROR	 	= 1
    Const EVENT_LEVEL_WARNING 	= 2
    Const EVENT_LEVEL_INFO 			= 4
    
    Const SCRIPT_STARTED				= 801
    Const CLASS_CREATED				= 802
    Const RELATIONSHIP_CREATED	= 803
    Const SCRIPT_ENDED					= 805
    
    'Setup variables sent in through script arguments
    SourceId = WScript.Arguments(0) 				'GUID of discovery calling the script. Provided by the MPElement variable.
    ManagedEntityId = WScript.Arguments(1)			'GUID of target object. Provided by the Target/Id variable.
    sComputerName = WScript.Arguments(2)			'Name of the computer holding the Store Server or Store Client class.
    sStoreCode = WScript.Arguments(3)				'StoreCode of the Store to create. Taken from the registry of the target computer.
    sServerOrClient = LCase(WScript.Arguments(4))	'String of "server" or "client" depending on which type of class is calling script.
    bDebug = CBool(WScript.Arguments(5))			'If true, information events are loggged.
    
    
    'Start by setting up API object and creating a discovery data object.
    'Discovery data object requires the MPElement and Target/ID variables. The first argument in the method is always 0.
    Set oAPI = CreateObject("MOM.ScriptAPI")
    Set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
    
    'Log a message that script is starting only if Debug argument is True
    sMessage =	"Script started" & VbCrLf & _
    			"Source ID: " & SourceId & VbCrLf & _
    			"Managed Entity ID: " & ManagedEntityId & VbCrLf & _
    			"Computer Name: " & sComputerName & VbCrLf & _
    			"Store Code: " & sStoreCode & VbCrLf & _
    			"Server or Client: " & sServerOrClient
    Call LogDebugEvent(SCRIPT_STARTED,sMessage)
    
    
    'Create an instance of the store class and add it to the discovery data.
    'The StoreCode property is required because it is the key property of the class.
    Set oStoreInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Demo.StoreApp.Store']$")
    oStoreInstance.AddProperty "$MPElement[Name='Demo.StoreApp.Store']/StoreCode$", sStoreCode
    oDiscoveryData.AddInstance(oStoreInstance)
    
    sMessage =	"Created store class" & VbCrLf & _
    			"Store Code: " & sStoreCode
    Call LogDebugEvent(CLASS_CREATED,sMessage)
    
    'Create an instance of the appropriate classes depending on whether a Store Server or Store Client is calling the script.
    If sServerOrClient = "server" Then
    	'Create a class instance of Store Server and a Relationship Instance of Store Contains Store Server.
    	Set oComputerInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Demo.StoreApp.ComputerRole.StoreServer']$")
    	Set oRelationshipInstance = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='Demo.StoreApp.StoreContainsStoreServer']$")	
    Else
    	'Create a class instance of Store Client and a Relationship Instance of Store Contains Store Client.
    	Set oComputerInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Demo.StoreApp.ComputerRole.StoreClient']$")
    	Set oRelationshipInstance = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='Demo.StoreApp.StoreContainsClients']$")	
    End If
    
    
    'Provide the PrincipalName property for the computer instance created above and add to the discovery data.
    'This is required because both the Store Server and Store Client classes are based on Windows ComputerRole.
    '	Windows ComputerRole is hosted by Windows Computer.
    '	When creating a new instance of a class, we need to provide the key properties of that class and any hosting classes.
    oComputerInstance.AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", sComputerName
    oDiscoveryData.AddInstance(oComputerInstance)
    
    sMessage =	"Created computer role class" & VbCrLf & _
    			"Computer Name: " & sComputerName
    Call LogDebugEvent(CLASS_CREATED,sMessage)
    
    'With the instance of Store and either Store Server or Store Client created, we can set the Source and Target of the relationship.
    oRelationshipInstance.Source = oStoreInstance
    oRelationshipInstance.Target = oComputerInstance
    oDiscoveryData.AddInstance(oRelationshipInstance)
    
    sMessage =	"Created relationship"
    Call LogDebugEvent(RELATIONSHIP_CREATED,sMessage)
    
    'Return the discovery data.
    oAPI.Return(oDiscoveryData)
    
    Call LogDebugEvent (SCRIPT_ENDED,"Script ended.")
    
    '==================================================================================
    ' Sub:		LogDebugEvent
    ' Purpose:	Logs an informational event to the Operations Manager event log 
    '			only if Debug argument is true
    '==================================================================================
    Sub LogDebugEvent(EventNo,Message)
    
    	Message = VbCrLf & Message
    	If bDebug = True Then
      	Call oAPI.LogScriptEvent(SCRIPT_NAME,EventNo,EVENT_LEVEL_INFO,Message)
    	End If
    	
    End Sub 
    
    ]]></ScriptBody>
            <TimeoutSeconds>300</TimeoutSeconds>
           </DataSource>
          </MemberModules>
          <Composition>
           <Node ID="Script" />
          </Composition>
         </Composite>
        </ModuleImplementation>
        <OutputType>System!System.Discovery.Data</OutputType>
       </DataSourceModuleType>
    
    Friday, October 1, 2010 4:58 PM
  • So yes.  The pattern you are showing, assuming your probe is in a discovery that targets the class your registry key is discovering, is called "picture painter" (which differes from seed pattern by not being able to have the seed host the computer role or windows application derivative).

    The script needs to use WMI to check for the same registry key, and if it is not present, it must return a blank payload.  This will allow the MP to successfully undiscover the app if the app is uninstalled (or the computer is unmarked).

    The script should also discover the seed again so that it does not get deleted - if the target of your script base discovery disappears, in your case, the seed?, then the script will not run again and your monitoring will not cease should you uninstall.


    Microsoft Corporation
    • Marked as answer by _Jason_ Friday, October 1, 2010 8:05 PM
    Friday, October 1, 2010 6:10 PM