selectline-software / selectline-api

Apache License 2.0
24 stars 5 forks source link

409 Conflict beim Anlegen eines Interessenten (POST /Prospects) #377

Open timothy3001 opened 3 months ago

timothy3001 commented 3 months ago

Bei einem unserer Kunden setzen wir die SelectLine-REST-API ein, um automatisiert Interessenten in SelectLine anzulegen. Dazu nutzen wir folgenden SelectLine-REST-API-Endpunkt:

POST /Prospects

In manchen Fällen (sehr unregelmäßig) bekommen wir einen 409 Conflict als HTTP Antwort. In der Doku konnte ich nichts zu dem Status-Code finden und wir können diesen Fehler nicht provozieren.

Unsere Vermutung ist, dass es evtl. mit der Auslastung von SelectLine zu tun hat und Ressourcen zufällig blockiert sind. Wir haben bereits einen "Retry"-Mechanismus hinzugefügt, der aber nicht immer korrekt greift.

Da der Fehler nicht dokumentiert ist, könnten Sie uns vielleicht mitteilen, was mögliche Ursachen für den 409 beim POST eines Interessenten sein könnten?

Details

Steps to replicate the behavior:

unbekannt

MatthiasGuse commented 3 months ago

Hallo,

was schicken Sie beispielhaft im Body mit?

In der Regel steht die Ursache in der Message des Response-Bodys. Bspw. "Prospect 'xyz' existiert bereits."

Grüße

timothy3001 commented 3 months ago

Ok, vielen dank schonmal. Im Body beim Senden des Interessenten stehen eigentlich gültige Daten, insbesondere Duplikate prüfen wir vorher, da der Kunde dies tatsächlich auch vorab schon gewünscht hat.

Ich füge unserem Code Trace-Logging hinzu und melde mich, sobald der Fehler wieder aufgetreten ist. Dann sehen wir vielleicht schon was die Ursache ist. Ich melde mich dann erneut und schließe das Issues ggfs.

Micha-Richter commented 3 months ago

Eventuell ist es ein Zeitproblem: die API hat Probleme damit, schnell hintereinander neue Datensätze anzulegen (das betrifft vermutlich alle POST's, bei denen die Nummer des neuen Datensatzes beim Aufruf NICHT mitgegeben wird).

Die folgenden parallelen Aufrufe ('&' am Ende der ersten Zeile!) führen bei mir immer zu einem "Conflict" im Statuscode bei einem der beiden POST's:

curl -kX POST "https://.../slmobileApi/Prospects" -H  "accept: application/json" -H  "Authorization: LoginId ...." -H  "Content-Type: application/json" -d "{  \"FirstName\": \"Michael\",  \"LastName\": \"Richter\",  \"Address\": {    \"Street\": \"Lindenstraße 22a\",    \"City\": \"Dolle\",    \"ZipCode\": \"39517\"  },  \"Contact\": {    \"EMail1\": \"mrichter@mrappware.de\"  }}" &
curl -kX POST "https://.../slmobileApi/Prospects" -H  "accept: application/json" -H  "Authorization: LoginId ...." -H  "Content-Type: application/json" -d "{  \"FirstName\": \"Michael\",  \"LastName\": \"Richter\",  \"Address\": {    \"Street\": \"Lindenstraße 22a\",    \"City\": \"Dolle\",    \"ZipCode\": \"39517\"  },  \"Contact\": {    \"EMail1\": \"mrichter@mrappware.de\"  }}"

Eins der beiden POST's legt erfolgreich einen neuen Datensatz an und das andere POST bringt dann als Ergebnis:

{
  "StatusCode": "Conflict",
  "ResponseCode": "12-009",
  "ResponseId": 9,
  "ResponseIdDescription": "EntityAlreadyExistsException",
  "Message": "Prospect '11' existiert bereits.",
  "Details": null
}

('11' ist der gerade eben parallel angelegte Datensatz)

Besonders ärgerlich ist, dass wir hier über ein POST reden, dem keine Nummer für den Interessenten mitgegeben wird, die API überholt sich hier intern offensichtlich selbst.. 😐 Von außen lässt sich das mMn nur vermeiden, indem man solche POST's selbst serialisiert 🤷‍♂️

timothy3001 commented 2 months ago

Wir haben das Logging erweitert und konnten den Fehler mittlerweile nachstellen.

Ich kann leider gerade nicht auf das System zugreifen, sodass ich die exakte Fehlermeldung nicht habe (reiche ich nach). Aber: Es handelt sich bei uns auch um die "EntityAlreadyExistsException" Problematik.

Im Unterschied zu @Micha-Richter senden wir aber nur einen Request und erhalten den Fehler bereits.

Meine Vermutung: In SelectLine gibt es mittlerweile eine eigene Duplikatsprüfung für die Interessenten? Bzw. für die Tabelle CRM_Adressen.

@Micha-Richter Bei Ihnen sind beide CURL-Befehle identisch, wenn ich das richtig sehe. Haben Sie mal versucht, eine Adresse abzuwandeln?

@MatthiasGuse Können Sie evtl. etwas Licht ins Dunkel bringen? Falls ich mit meiner Theorie richtig liege würde ich mich freuen, wenn Sie uns noch sagen könnte, welche Teile geprüft werden. Also wird zum Beispiel die volle Adresse geprüft und der Name? Wie sieht es mit Telefonnummer und E-Mail aus, etc.

Micha-Richter commented 2 months ago

@Micha-Richter Bei Ihnen sind beide CURL-Befehle identisch, wenn ich das richtig sehe. Haben Sie mal versucht, eine Adresse abzuwandeln?

Ja, das ändert aber nichts (gerade noch einmal geprüft).

Und die Message im Ergebnis "Prospect '13' existiert bereits." deutet auch auf den SelectLine-Schlüssel in der Tabelle als Ursache, die eigentlichen Nutzerdaten spielen hier keine Rolle (ich kann zB immer wieder einen der beiden Datensätze anlegen, s. Screenshot):

image
timothy3001 commented 2 months ago

Stimmt, habe nochmal ein weiteres Beispiel gesucht, dort erkennt unsere Automatisierung kein Duplikat.

Wie versprochen, hier bei uns der Response Body beim POST auf /prospects:

{
  "StatusCode": "Conflict",
  "ResponseCode": "12-009",
  "ResponseId": 9,
  "ResponseIdDescription": "EntityAlreadyExistsException",
  "Message": "Prospect '1093326' existiert bereits.",
  "Details": null
}
MatthiasGuse commented 2 months ago

Hallo,

sofern niemand die Datensatzschlüssel manipuliert, kann das eigentlich nur durch gleichzeitige Zugriffe vorkommen. Ich werde für einen Workaround ein Workitem bei uns erfassen. Hier muss die API toleranter werden und mit solchen Fällen umgehen können. Einen zeitlichen Horizont kann ich allerdings aktuell noch nicht nennen.

Viele Grüße