I am having an issue in my production environment this worked fine in a test lab but not production Solarwinds.
The error in the discovery is
A Network Discovery job has failed to complete.\r\nState: Failed\r\nProfile id: 106.\r\nThe Job Scheduler is reporting the following error:\r\nSolarWinds.JobEngine.WorkerProcess.JobExecutionException: System.Exception: Unable to deserialize job description. ---> System.Runtime.Serialization.SerializationException: Error in line 0 position 0. Element 'http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Models.Discovery:DiscoveryPluginJobDescriptionBase' contains data from a type that maps to the name 'http://schemas.solarwinds.com/2008/DeviceStudio:DeviceStudioDiscoveryPluginJobDescription'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'DeviceStudioDiscoveryPluginJobDescription' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.
Here is the code :
public HttpResponseMessage Post([FromBody]NodeInfo info)
{
CustomNodeInfo cnInfo = new CustomNodeInfo();
#region Hard Coded Values for SaaS
//Hard coding these for now as this is for just the SaaS Poller currently
info.EngineID = 12;
cnInfo.Custom1 = "1";
cnInfo.Custom2 = "2";
cnInfo.Custom3 = "3";
//End Hard Coded
#endregion
info.ObjectSubType = "SNMP";
info.SNMPVersion = "2";
info.EntityType = "Orion.Nodes";
info.DynamicIP = false;
info.Status = 1;
info.UnManaged = false;
info.Allow64BitCounters = false;
if (ModelState.IsValid)
{
string query = "{\"query\":\"SELECT PropertyValue FROM Orion.EngineProperties WHERE EngineID=@e AND PropertyName='Orion.Standard.Polling'\",\"parameters\":{\"e\":" + info.EngineID + "}}";
JObject pollingRate = JObject.Parse(SWJsonCall.Post("Json/Query", query));
int curRate = (Int32)pollingRate["results"][0]["PropertyValue"];
if (curRate < 85)
{
#region Start Discovery on New Node
var dis = new DiscoveryInfo
{
Name = "API Add Node " + info.IPAddress,
EngineID = info.EngineID,
JobTimeoutSeconds = 3600,
SearchTimeoutMiliseconds = 5000,
SnmpTimeoutMiliseconds = 5000,
SnmpRetries = 2,
RepeatIntervalMiliseconds = 1800,
SnmpPort = 161,
HopCount = 0,
PreferredSnmpVersion = "SNMP2c",
DisableIcmp = false,
AllowDuplicateNodes = true,
IsAutoImport = true,
IsHidden = false,
};
dis.PluginConfigurations = new List<PluginItems> { new PluginItems { PluginConfigurationItem = DiscoveryProfiles.SNMPv2(info.Community, info.IPAddress) } };
DiscoveryInfo[] disArray = new DiscoveryInfo[] { dis };
string createDiscovery = SWJsonCall.Post("Json/Invoke/Orion.Discovery/StartDiscovery", JsonConvert.SerializeObject(disArray));
#endregion
JObject disStatus = null;
Stopwatch time = new Stopwatch();
time.Start();
do
{
string statusQuery = "{\"query\":\"SELECT Status,StatusDescription FROM Orion.DiscoveryProfiles where ProfileID=@id\",\"parameters\":{\"id\":\"" + createDiscovery + "\"}}";
disStatus = JObject.Parse(SWJsonCall.Post("Json/Query", statusQuery));
if (time.ElapsedMilliseconds > 120000) return Request.CreateResponse(HttpStatusCode.RequestTimeout, "This has taken over 120 seconds it should not take that long this might be something wrong with the information provided.");
} while (disStatus["results"][0]["Status"].ToString() == "0" || disStatus["results"][0]["Status"].ToString() == "1" || !disStatus["results"].HasValues);
if (disStatus["results"][0]["Status"].ToString() == "2")
{
string nodeQuery = "{\"query\":\"SELECT Uri,NodeID FROM Orion.Nodes where IPAddress=@ip AND EngineID=@e\",\"parameters\":{\"ip\":\"" + info.IPAddress + "\", \"e\": " + info.EngineID + "}}";
JObject nodeStatus = JObject.Parse(SWJsonCall.Post("Json/Query", nodeQuery));
string swisUrl = nodeStatus["results"][0]["Uri"].ToString();
string updateProps = SWJsonCall.Post("Json/" + swisUrl + "/CustomProperties", JsonConvert.SerializeObject(cnInfo));
}
else return Request.CreateResponse(HttpStatusCode.ExpectationFailed, disStatus["results"][0]["StatusDescription"].ToString());
return new HttpResponseMessage(HttpStatusCode.Created);
}
else
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, "Polling rate at dangerous level " + curRate + "%. Please consult Admins, node NOT added.");
}
}
else
{
var message = string.Join(" | ", ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage));
var execption = string.Join(" | ", ModelState.Values.SelectMany(v => v.Errors).Select(e => e.Exception));
return Request.CreateResponse(HttpStatusCode.BadRequest, "Error - " + message + " : " + execption);
}
}
Here is the discovery profile model.
public static string SNMPv2(string community, string ipaddress)
{
string discoveryProfileXML = "<PluginItems xmlns=\"http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Models.Discovery\">\n" +
"<knownTypes>\n" +
"<ArrayOfstring xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
"<string>SolarWinds.Orion.Core.Models.Discovery.CoreDiscoveryPluginConfiguration,SolarWinds.Orion.Core.Models</string>\n" +
"</ArrayOfstring>\n" +
"</knownTypes>\n" +
"<pluginItem>\n" +
"<ArrayOfDiscoveryPluginConfigurationBase xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
"<DiscoveryPluginConfigurationBase i:type=\"d2p1:CoreDiscoveryPluginConfiguration\" xmlns:d2p1=\"http://schemas.solarwinds.com/2008/Orion\">\n" +
"<d2p1:AddressRange/>\n" +
"<d2p1:AgentsAddresses xmlns:d3p1=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\"/>\n" +
"<d2p1:BulkList xmlns:d3p1=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">\n" +
"<d3p1:string>"+ipaddress+"</d3p1:string>\n" +
"</d2p1:BulkList>\n" +
"<d2p1:Credentials>\n" +
"<d2p1:credentials>\n" +
"<knownTypes>\n" +
"<ArrayOfstring xmlns=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">\n" +
"<string>SolarWinds.Orion.Core.Models.Credentials.SnmpCredentialsV2,SolarWinds.Orion.Core.Models</string>\n" +
"</ArrayOfstring>\n" +
"</knownTypes>\n" +
"<pluginItem>\n" +
"<d2p1:ArrayOfCredential>\n" +
"<d2p1:Credential i:type=\"d2p1:SnmpCredentialsV2\">\n" +
"<d2p1:Description i:nil=\"true\"/>\n" +
"<d2p1:ID i:nil=\"true\"/>\n" +
"<d2p1:IsBroken>false</d2p1:IsBroken>\n" +
"<d2p1:Name>"+community+"</d2p1:Name>\n" +
"<d2p1:Owner i:nil=\"true\"/>\n" +
"<d2p1:Community>"+community+"</d2p1:Community>\n" +
"</d2p1:Credential>\n" +
"</d2p1:ArrayOfCredential>\n" +
"</pluginItem>\n" +
"</d2p1:credentials>\n" +
"</d2p1:Credentials>\n" +
"<d2p1:DiscoverAgentNodes>false</d2p1:DiscoverAgentNodes>\n" +
"<d2p1:SharedCredentials xmlns:d3p1=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\"/>\n" +
"<d2p1:SubnetList/>\n" +
"<d2p1:WmiRetries>1</d2p1:WmiRetries>\n" +
"<d2p1:WmiRetryInterval>PT10S</d2p1:WmiRetryInterval>\n" +
"</DiscoveryPluginConfigurationBase>\n" +
"</ArrayOfDiscoveryPluginConfigurationBase>\n" +
"</pluginItem>\n" +
"</PluginItems>\n";
return discoveryProfileXML;
}