How to Create Inbound Connectors

Updated: January 31, 2012

Applies To: System Center 2012 - Operations Manager

You can use inbound connectors to insert performance, event, and alert data into Operations Manager from an external management system. The following process describes how to implement an inbound connector:

  1. Create a new instance of the MonitoringConnector class. This process is shown in the CreateConnector method in the following code example.

  2. Write a management pack that describes the application model for the application that the data is inserted into. Define the health model for the application by defining monitors and rules that interpret the performance and event data that is inserted through the connector. This code example uses the following XML for the management pack that is saved in the C:\Program Files\Microsoft System Center 2012\Operations Manager\SdkDemo.DiscoveryDataInsertion.xml file.

    <ManagementPack xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ContentReadable="true">
      <Manifest>
    	<Identity>
    	<ID>SdkDemo.DiscoveryDataInsertion</ID>
    	<Version>1.0.0.0</Version>
    	</Identity>
    	<Name>System Health Library</Name>
    	<References>
    	<Reference Alias="System">
    		<ID>System.Library</ID>
    		<Version>6.0.5000.0</Version>
    		<PublicKeyToken>9396306c2be7fcc4</PublicKeyToken>
    	</Reference>
    	<Reference Alias="SystemCenter">
    		<ID>Microsoft.SystemCenter.Library</ID>
    		<Version>6.0.5000.0</Version>
    		<PublicKeyToken>9396306c2be7fcc4</PublicKeyToken>
    	</Reference>
    	</References>
      </Manifest>
      <TypeDefinitions>
    	<EntityTypes>
    	<ClassTypes>
    		<ClassType ID="SdkDemo.DiscoveryDataInsertion.RouterFan" Accessibility="Public" Abstract="false" Base="System!System.LogicalHardware" Hosted="false" Singleton="false">
    		<Property ID="FanId" Type="string" Key="true" CaseSensitive="false" Length="256" MinLength="1" />
    		</ClassType>
    		<ClassType ID="SdkDemo.DiscoveryDataInsertion.Router" Accessibility="Public" Abstract="false" Base="System!System.LogicalHardware" Hosted="false" Singleton="false">
    		<Property ID="RouterId" Type="string" Key="true" CaseSensitive="false" Length="256" MinLength="1" />
    		</ClassType>
    		<ClassType ID="SdkDemo.DiscoveryDataInsertion.RouterPort" Accessibility="Public" Abstract="false" Base="System!System.LogicalHardware" Hosted="true" Singleton="false">
    		<Property ID="PortId" Type="string" Key="true" CaseSensitive="false" Length="256" MinLength="1" />
    		</ClassType>
    	</ClassTypes>
    	<RelationshipTypes>
    		<RelationshipType ID="SdkDemo.DiscoveryDataInsertion.RouterHostsPort" Accessibility="Public" Abstract="false" Base="System!System.Hosting">
    		<Source>SdkDemo.DiscoveryDataInsertion.Router</Source>
    		<Target>SdkDemo.DiscoveryDataInsertion.RouterPort</Target>
    		</RelationshipType>
    		<RelationshipType ID="SdkDemo.DiscoveryDataInsertion.RouterContainsFan" Accessibility="Public" Abstract="false" Base="System!System.Containment">
    		<Source>SdkDemo.DiscoveryDataInsertion.Router</Source>
    		<Target>SdkDemo.DiscoveryDataInsertion.RouterFan</Target>
    		</RelationshipType>
    	</RelationshipTypes>
    	</EntityTypes>
      </TypeDefinitions>
      <Presentation>
    	<Views>
    	<View ID="View_2e1517f838d44e87892c28fb4aa4c9dd" Accessibility="Public" Enabled="true" Target="SdkDemo.DiscoveryDataInsertion.Router" TypeID="SystemCenter!Microsoft.SystemCenter.StateViewType" Visible="true">  
    		<Category>Operations</Category>
    		<Criteria>
    			<InMaintenanceMode>false</InMaintenanceMode>
    		</Criteria>
    		<Presentation>
    			<ColumnInfo Index="0" SortIndex="0" Width="100" Grouped="false" Sorted="true" IsSortable="true" Visible="true" SortOrder="Descending">
    			<Name>State</Name>
    			<Id>SdkDemo.DiscoveryDataInsertion.Router</Id>
    			</ColumnInfo>
    			<ColumnInfo Index="1" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
    			<Name>Maintenance Mode</Name>
    			<Id>InMaintenanceMode</Id>
    			</ColumnInfo>
    			<ColumnInfo Index="2" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
    			<Name>Name</Name>
    			<Id>Name</Id>
    			</ColumnInfo>
    			<ColumnInfo Index="3" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
    			<Name>Path</Name>
    			<Id>Path</Id>
    			</ColumnInfo>
    			<ColumnInfo Index="4" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
    			<Name>RouterId</Name>
    			<Id>RouterId</Id>
    			</ColumnInfo>
    			<ColumnInfo Index="5" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
    			<Name>Display Name</Name>
    			<Id>DisplayName</Id>
    			</ColumnInfo>
    			<ColumnInfo Index="6" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="false" Visible="false" SortOrder="Ascending">
    			 <Name>SdkDemo.DiscoveryDataInsertion.RouterPort</Name>
    			 <Id>SdkDemo.DiscoveryDataInsertion.RouterPort</Id>
    			</ColumnInfo>
    			<ColumnInfo Index="7" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="false" Visible="false" SortOrder="Ascending">
    			<Name>SdkDemo.DiscoveryDataInsertion.RouterFan</Name>
    			<Id>SdkDemo.DiscoveryDataInsertion.RouterFan</Id>
    			</ColumnInfo>
    		</Presentation>
    		<Target />
    	</View>
    	</Views>
    	<Folders>
    	<Folder ID="Folder_8af62648e14e43b5be50724d5ab94d0a" Accessibility="Public" ParentFolder="SystemCenter!Microsoft.SystemCenter.Monitoring.ViewFolder.Root" />
    	</Folders>
    	<FolderItems>
    	<FolderItem ElementID="View_2e1517f838d44e87892c28fb4aa4c9dd" Folder="Folder_8af62648e14e43b5be50724d5ab94d0a" />
    	</FolderItems>
      </Presentation>
      <LanguagePacks>
    	<LanguagePack ID="ENU" IsDefault="false">
    	<DisplayStrings>
    		<DisplayString ElementID="SdkDemo.DiscoveryDataInsertion">
    		<Name>SDK Demo - Inserting Discovery Data</Name>
    		<Description></Description>
    		</DisplayString>
    		<DisplayString ElementID="Folder_8af62648e14e43b5be50724d5ab94d0a">
    		<Name>Sdk Demo Views</Name>
    		</DisplayString>
    		<DisplayString ElementID="View_2e1517f838d44e87892c28fb4aa4c9dd">
    		<Name>Router State</Name>
    		<Description></Description>
    		</DisplayString>
    	</DisplayStrings>
    	</LanguagePack>
      </LanguagePacks>
    </ManagementPack>
    
  3. Import the management pack into Operations Manager.

  4. Insert the discovery data.

  5. Insert performance and event data.

The following example shows how to create an inbound connector that you can use to insert data into Operations Manager from an external management system:

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Microsoft.EnterpriseManagement.Administration;
using Microsoft.EnterpriseManagement;
using Microsoft.EnterpriseManagement.Monitoring;
using Microsoft.EnterpriseManagement.ConnectorFramework;
using Microsoft.EnterpriseManagement.Common;
using Microsoft.EnterpriseManagement.Configuration;
using Microsoft.EnterpriseManagement.Configuration.IO;
using System.Collections.ObjectModel;
using System.IO;

namespace DiscoveryDataInsertion
{
	class Program
	{
		static void Main(string[] args)
		{
			DiscoveryDataInsertionSample insertionSample = new DiscoveryDataInsertionSample("localhost");

			insertionSample.InsertDiscoveryData();

	}
}

   class DiscoveryDataInsertionSample
	{
		ManagementGroup	 m_managementGroup;
		MonitoringConnector m_monitoringConnector;
		MonitoringObject	m_routerMonitoringObject;
		MonitoringObject	m_routerPortMonitoringObject;
		MonitoringObject	m_routerFanMonitoringObject;

		public DiscoveryDataInsertionSample(
			string managementServerName
			)
		{
			Debug.Assert(managementServerName.Length > 0);

			ConnectToManagementGroup(managementServerName);

			CreateConnector();

			ImportMPIfNeed();
	}

		public void InsertDiscoveryData()
		{
			SnapshotDiscoveryData discoveryData = new SnapshotDiscoveryData();
			ManagementPackClass routerClass;
			ManagementPackClass routerPortClass;
			ManagementPackClass routerFanClass;
			ManagementPackClass					 entityClass;
			ManagementPackRelationship		 fanContainedInRouterRelationshipClass;
			CreatableEnterpriseManagementObject			routerMonitoringObject;
			CreatableEnterpriseManagementObject routerPortObject;
			CreatableEnterpriseManagementObject routerFanMonitoringObject;
			CreatableEnterpriseManagementRelationshipObject relationshipObject;
			ManagementPackProperty			 routerIdProp;
			ManagementPackProperty portIdProp;
			ManagementPackProperty fanIdProp;
			ManagementPackProperty displayNameProp;


			routerClass = GetManagementPackClass("SdkDemo.DiscoveryDataInsertion.Router");
			routerPortClass = GetManagementPackClass("SdkDemo.DiscoveryDataInsertion.RouterPort");
			routerFanClass = GetManagementPackClass("SdkDemo.DiscoveryDataInsertion.RouterFan");
			entityClass = GetManagementPackClass("System.Entity");
			fanContainedInRouterRelationshipClass = GetManagementPackRelationship("SdkDemo.DiscoveryDataInsertion.RouterContainsFan");
		
			routerIdProp	= routerClass.PropertyCollection["RouterId"];
			portIdProp	= routerPortClass.PropertyCollection["PortId"];
			fanIdProp	 = routerFanClass.PropertyCollection["FanId"];
			displayNameProp = entityClass.PropertyCollection["DisplayName"];

			routerMonitoringObject = new CreatableEnterpriseManagementObject(m_managementGroup, routerClass);
			routerPortObject = new CreatableEnterpriseManagementObject(m_managementGroup, routerPortClass);
			routerFanMonitoringObject = new CreatableEnterpriseManagementObject(m_managementGroup, routerFanClass);
			relationshipObject = new CreatableEnterpriseManagementRelationshipObject(m_managementGroup, fanContainedInRouterRelationshipClass);

			routerMonitoringObject[routerIdProp].Value = "1";
			routerMonitoringObject[displayNameProp].Value = "Router 123";

			//There is a hosting relationship between the router and the router port.
			//For Operations Manager to know what router it needs to associate with the port object, 
			//we have to set the key prop of the router (RouterId) on the hosted object(RouterPort).
			//There is no need to explicitly create a relationship object for relationships of type hosting.
			//An instance of the relationship is created automatically.
	 
			routerPortObject[routerIdProp].Value= "1";
			routerPortObject[portIdProp].Value=  "1";
			routerPortObject[displayNameProp].Value=  "Port #1";

			routerFanMonitoringObject[fanIdProp].Value=  "1";
			routerFanMonitoringObject[displayNameProp].Value=  "Fan #1";

			relationshipObject.SetSource(routerMonitoringObject);
			relationshipObject.SetTarget(routerFanMonitoringObject);

			discoveryData.Include(routerPortObject);
			discoveryData.Include(routerMonitoringObject);
			discoveryData.Include(routerFanMonitoringObject);
			discoveryData.Include(relationshipObject);

			discoveryData.Commit(m_monitoringConnector);

			// Obtain references to the newly created objects.
			// They are used to insert events and performance data.
			m_routerMonitoringObject = m_managementGroup.EntityObjects.GetObject<MonitoringObject>((Guid)routerMonitoringObject.Id, ObjectQueryOptions.Default);
			m_routerPortMonitoringObject = m_managementGroup.EntityObjects.GetObject<MonitoringObject>((Guid)routerPortObject.Id, ObjectQueryOptions.Default);
			m_routerFanMonitoringObject = m_managementGroup.EntityObjects.GetObject<MonitoringObject>((Guid)routerFanMonitoringObject.Id, ObjectQueryOptions.Default);
	}

		private void ConnectToManagementGroup(string managementServerName)
		{
			m_managementGroup = new ManagementGroup(managementServerName);
	}

		//---------------------------------------------------------------------
		private void CreateConnector()
		{
	
			Guid connectorGuid = new Guid("DE1FC259-FE16-44ce-B90E-708CADE55909");
			IConnectorFrameworkManagement cfMgmt = m_managementGroup.ConnectorFramework;

			try
			{
				m_monitoringConnector = cfMgmt.GetConnector(connectorGuid);
		}
			catch (Microsoft.EnterpriseManagement.Common.ObjectNotFoundException)
			{
				//The connector does not exist, so create it.

				ConnectorInfo connectorInfo = new ConnectorInfo();

				connectorInfo.Description = "This is a sample connector to demonstrate discovery data insertion";
				connectorInfo.DisplayName = "Sample connector";
				connectorInfo.Name = "Sample connector";

				m_monitoringConnector = cfMgmt.Setup(connectorInfo, connectorGuid);
		}

			if (!m_monitoringConnector.Initialized)
			{
				m_monitoringConnector.Initialize();
		}
	}

		private ManagementPackClass GetManagementPackClass(
			string className
			)
		{
			IList<ManagementPackClass> mpClasses;

			mpClasses = m_managementGroup.EntityTypes.GetClasses(new ManagementPackClassCriteria("ID='" + className + "'"));

			if (mpClasses.Count == 0)
			{
				throw new ApplicationException("Failed to find management pack class " + className);
		}

			return (mpClasses[0]);
	}

		private ManagementPackRelationship GetManagementPackRelationship(
			string relationshipName
			)
		{
			IList<ManagementPackRelationship> relationshipClasses;

			relationshipClasses = m_managementGroup.EntityTypes.GetRelationshipClasses(new ManagementPackRelationshipCriteria("Name='" + relationshipName +"'"));

			if (relationshipClasses.Count == 0)
			{
				throw new ApplicationException("Failed to find monitoring relationship " + relationshipName);
		}

			return (relationshipClasses[0]);
	}

		private void ImportMPIfNeed()
		{
			ManagementPackCriteria criteria = new ManagementPackCriteria("Name = 'SdkDemo.DiscoveryDataInsertion'");

			if (m_managementGroup.ManagementPacks.GetManagementPacks(criteria).Count == 0)
			{
			 
				string mgmtPackPath = @"C:\Program Files\System Center Operations Manager 2007\SdkDemo.DiscoveryDataInsertion.xml";
				ManagementPack mp = new ManagementPack(mgmtPackPath);
				 
				m_managementGroup.ManagementPacks.ImportManagementPack(mp);

		}					
	}
}
}