2016-08-18 5 views
2

Ich versuche, ALLE Daten aus den ServiceNow CMDB-Datentabellen in meine eigene SQL-Datenbank zu ziehen. Ich plane, dies für automatisierte Aktualisierungen zu verwenden, wenn Daten in einem Kunden-Altsystem gepflegt werden, das mit der neuen SN-Implementierung synchronisiert werden muss.ServiceNow-Tabellen-API, die Duplikate zurückgibt/nicht alle Datensätze zurückgibt

Unsere SN-Umgebung hat viele Domänen, viele Kunden usw. Das bedeutet eine riesige Menge an Daten. Wenn versucht wird, ALLE Datensätze in einem einzelnen API-Aufruf abzurufen, führt dies natürlich zu einer Zeitüberschreitungsausnahme, da die Daten zu groß sind. Die Web-API schlägt Daten Dosierung, das ist, was ich umgesetzt haben:

 ... 
     var offset = 0; 

     while (true) 
     { 
      var requestUrl = string.Format("{0}/api/now/table/cmdb_ci_vm_instance?sysparm_offset={1}&sysparm_limit={2}&sysparm_exclude_reference_link=true", url, offset, batchSize); 
      var result = ApiRequest.Get(new Uri(requestUrl), _credential, null, out response); 
      if (result == HttpStatusCode.OK) 
      { 
       var virtualmachineRo = JsonConvert.DeserializeObject<VirtualMachineRootObject>(response); 

       if (virtualmachineRo.result.Count < batchSize) 
       { 
        virtualmachines.AddRange(virtualmachineRo.result); 
        break; 
       } 

       virtualmachines.AddRange(virtualmachineRo.result); 
       offset += virtualmachineRo.result.Count; 
      } 
      else 
      { 
       break; 
      } 
     } 
     .... 

I mit unterschiedlichen Chargengrößen gearbeitet haben, und es gibt mir unterschiedliche Ergebnisse. Abhängig davon, welche Tabelle ich treffe, bekomme ich manchmal Duplikate, manchmal nicht, manchmal bekomme ich andere Duplikate. In fast allen Fällen, wenn ich DO ein Duplikat bekomme, ersetzt das Duplikat einen gültigen Datensatz im Stream, was bedeutet, dass ich einen gültigen Datensatz "vermisse".

Ich habe dies bestätigt, indem ich den rohen Datenstrom von serviceNow betrachte und die Duplikate sehe und überprüfe, dass es Datensätze in ServiceNow gibt, die nicht in meinem Stream angezeigt werden (was normalerweise beim Versuch entdeckt wird, einen fehlender Datensatz und SN antwortet mit "ignored - no field changed" zeigt an, dass der Datensatz bereits vorhanden ist.)

Ich habe versucht, jemanden mit ähnlichen Problemen zu suchen und zu finden, aber nichts gefunden. Bevor ich ein Ticket mit SN direkt geöffnet habe, habe ich gehofft zu sehen, ob ich irgendetwas falsch mit meinem Code gemacht habe, oder ob es das zu sein scheint, was ich erwarte - ein plattformbezogener Bug.

Antwort

2

So dies zu Dienstkonto Zugriff im Zusammenhang mit ziemlicher Sicherheit um einen Fehler in ihrer API ist. (! Und meine Arbeit um) Hier ist, was ich getan habe, und was ich glaube zu vorkommendes

Nach Herumspielen mit einigen anderen Logik, begegnete ich folgendes:

{0}/api/now/table/cmdb_ci_vm_instance?sysparm_offset=0&sysparm_limit=750&sysparm_exclude_reference_link=true&sysparm_query=ORDERBYsys_id 
2016-08-19 12:46:15,277 [INFO ] Returned Records Count: 750 

{0}/api/now/table/cmdb_ci_vm_instance?sysparm_offset=750&sysparm_limit=750&sysparm_exclude_reference_link=true&sysparm_query=ORDERBYsys_id 
2016-08-19 12:46:28,243 [INFO ] Returned Records Count: 746 

Mitteilung über den zweiten Durchgang Ich fragte nach 750 Datensätzen, aber nur 746 (ein Unterschied von 4). Die anderen Chargen fuhren fort, 750 als normal zurückzugeben, und am Ende habe ich genau 4 Duplikate aus mehr als 5200 gesammelten Aufzeichnungen erhalten. Da der zweite Durchlauf weniger als die 750 zurückgab, die ich verlangte, brach mein Code, da er dachte, dass die Daten vollständig waren ...

Um das (anfänglich) zu umgehen, tat ich folgendes dem obigen Code:

if (virtualmachineRo.result.Count == 0) 
{ 
    //AddRange(virtualmachineRo.result); 
    break; 
} 

ich nicht mehr darauf vertrauen, dass nur, weil die Anzahl der zurückgegebenen Datensätze geringer war als die sysparm_limit, dass ich alle Datensätze abgerufen haben.

Es sieht so aus, als wenn die Daten aus der Datenbank abgerufen werden, ein separater Prozess die Daten basierend auf Ihren Berechtigungen filtert. Daher entfernt der zweite Batch 4 Datensätze - aber die Datenbank weiß es nicht besser ...Beim nächsten Durchlauf, als ich meinen Offset um die tatsächliche Zählung, die von dem Aufruf von 746 zurückgegeben wurde, inkrementiert hat, wird derselbe Datensatz zurückgegeben, und die letzten 4 Datensätze des Stapels werden als die ersten 4 Datensätze auf der nächsten Datenseite dupliziert. (Bestätigt im Datenstrom - wenn die Daten bestellt werden, bewirkt dies, dass die Duplikate an verschiedenen Stellen erscheinen und unterschiedliche Datensätze basierend auf der Losgröße/Reihenfolge dupliziert werden!)

Ich kann nicht glauben, dass dies das beabsichtigte Verhalten ist und es ist sicherlich nicht im Wiki dokumentiert. In jedem Fall ist die Problemumgehung für jeden, der darauf eingeht, einfach: Sie müssen weiterhin Daten ziehen, auch wenn die zurückgegebene Anzahl kleiner als die Batchgröße ist, und fortfahren, bis 0 Datensätze zurückgegeben werden. Dann müssen Sie die Duplikate mit etwas einfachen wie:

yourrecords.GroupBy(x => x.sys_id).Select(x => x.First()).ToList(); 

herausfiltern und Problem ist "gelöst."

0

Sie können versuchen, eine explizite Sortierung für den Primärschlüssel (sys_id) hinzuzufügen, um sicherzustellen, dass jede Batch-Abfrage gewährleistet ist. Sie können dies tun, indem das Hinzufügen des URL-Parameter sysparm_query=ORDERBYsys_id

Ihre URL aussehen würde: "{0}/api/now/table/cmdb_ci_vm_instance?sysparm_offset={1}&sysparm_limit={2}&sysparm_exclude_reference_link=true&sysparm_query=ORDERBYsys_id"

+0

Das klingt nach einer guten Arbeit - ich werde es jetzt versuchen. Wird zu dir zurückkommen. (Dies stimmt auch mit meiner Annahme überein - dass sie die Daten auf der SN-Seite nicht anordneten, bevor sie in der Charge zerschnitten wurden.) –

+0

Leider hat das nicht funktioniert - was noch seltsamer ist, wenn ich es nicht tue Batch und versuchen, den gesamten Datensatz zu ziehen (was viel zu groß ist), es Timeout ... aber gibt einen Teil Datensatz von 2000 bis 4000 Datensätze. Jedes Mal anders. Ich würde einen HTTP-Code von 408 oder etwas Ähnliches erwarten, aber stattdessen erhalte ich einen Teildatensatz mit einem Fehler, der in den Antwortstream eingebettet ist, aber immer noch ein HTTP 200. Sehr frustrierend = / –

Verwandte Themen