Inkompatible Responsmessage "infoDomain" via SOAP API

  • Hallo Community,


    infoDomain liefert im responsedata der Responsmessage 18 Parameter zurück. Diese sollte imho auf "tns:DomainObject" mappen, der aber nur 17 Parameter beinhaltet (siehe https://ccp.netcup.net/run/web…endpoint.php#DomainObject)


    Ich habe die Parameter überprüft, der zusätzliche Parameter ist die Info über "additional domain" oder "inklusiv..." etc. (an letzter Stelle in der Response)


    Ich kann den Parameter in meiner Python Lib "manuell" ausblenden bevor ich das DomainObject initialisiere, ist aber ein statischer Workaround, den ich ungern machen würde.

    Meine Python Lib holt sich die Typen über zeep.Client.get_type dynamisch vom Server. Die Responses sollten zu den Typen passen.


    Kann das ein Entwickler evtl. korrigieren?


    Vielen Dank und beste Grüße,

    Tom

  • infoDomain liefert eine Responsmessage mit 18 Parametern zurück. Diese sollte lt. API Beschreibung auf den Type "ns0:DomainObject" mappen

    Wo steht das denn für infoDomain? Finde das Mapping für den Aufruf nicht - nur an anderer Stelle.

  • Wo steht das denn für infoDomain? Finde das Mapping für den Aufruf nicht - nur an anderer Stelle.

    Puh, die typen-definition ist in der https://ccp.netcup.net/run/webservice/xsd/...simple bzw. complextypes.xsd definiert. Das mapping der response message auf den Typen muss ich auch nochmal suchen, keine Ahnung wo ich das herhabe, ist schon 2 Jahre her, dass ich die Lib implementiert habe.


    Wenn ich es finde, sage ich nochmal Bescheid

  • infoDomain liefert eine Responsmessage mit 18 Parametern zurück. Diese sollte lt. API Beschreibung auf den Type "ns0:DomainObject" mappen, der aber nur 17 Parameter beinhaltet (siehe https://ccp.netcup.net/run/web…endpoint.php#DomainObject)

    Ich schätze mal, dass in diesem Fall von 0 angefangen wird zu zählen. Also von 0 bis 17 = 18 Parameter. Denn in der Softwareentwicklung fängt man meistens mit 0 an zu zählen. Es sei denn es handelt sich hierbei z.B. um die Programmiersprache COBOl, welche mal für Kaufläute entwickelt wurde und bei 1 beginnt.

  • Ich schätze mal, dass in diesem Fall von 0 angefangen wird zu zählen. Also von 0 bis 17 = 18 Parameter. Denn in der Softwareentwicklung fängt man meistens mit 0 an zu zählen. Es sei denn es handelt sich hierbei z.B. um die Programmiersprache COBOl, welche mal für Kaufläute entwickelt wurde und bei 1 beginnt.

    8) ganz netter versuch. ich rede nicht von indexing, sondern ich rede von der Länge einer Liste (pythonisch für Array) Die Länge ist ein absoluter Wert, egal wo man anfängt zu indizieren.


    Aber trotzdem danke für den netten "Versuch" ;)

  • 8) ganz netter versuch. ich rede nicht von ... der Länge einer Liste (pythonisch für Array) ...

    Genau, das meinte ich auch. Du füllst ein Array bzw. eine Liste [0 - 17], welches von 0 beginnt und mit 17 endet, mit 18 Elementen.

    Z.B.

    Code
    [0] = Element 1
    [1] = Element 2
    […] = Element …
    [17] = Element 18
  • Genau, das meinte ich auch. Du füllst ein Array bzw. eine Liste [0 - 17], welches von 0 beginnt und mit 17 endet, mit 18 Elementen.

    Z.B.

    Code
    [0] = Element 1
    [1] = Element 2
    […] = Element …
    [17] = Element 18

    Lieber Andreas,


    du musst deinen Community-Mitstreitern zugestehen, dass sie zählen können.


    Bitte gehe zu dem Link den ich gepostet habe und zähle die Aufzählungen in der Liste (https://ccp.netcup.net/run/web…endpoint.php#DomainObject)

    Das sind 17 Parameter

    egal ob von 1 bis 17 oder von 0 bis 16


    Die Antwort des SOAP requests beinhaltet 18 Parameter

    egal ob von 1 bis 18 oder von 0 bis 17


    Spielt absolut keine Rolle.


    Viele Grüße,

    Dipl.-Ing. (Technische Informatik) Tom ;)


  • Ich habe mir mal das Objekt "Domain Object" genauer angeschaut und auch gezählt.

    Das 18 Element als Ergebnis ist bei diesen das Objekt selber. Siehe Index 18.

    Mehr siehe das PHP-Script DomainWebserviceSoapClient.php.

  • Ich habe mir mal das Objekt "Domain Object" genauer angeschaut und auch gezählt.

    Das 18 Element als Ergebnis ist bei diesen das Objekt selber. Siehe Index 18.

    Du hast dir den Kommentarblock der Klasse angeschaut. Weder das Objekt?? oder die Klassendefinition. Folgend dem Kommentar, den du manuell mit Aufzählungen versehen hast ist das "DomainObject" definiert. (Ab Zeile 597) - mit 17 Parametern... $dnssecentries ist der "letzte" Eintrag.


    Im Kommentar selbst steht halt unter den jeweiligen Klassen-Member noch der "complex type" aus dem xsd der von der Klasse abgebildet wird, ja, das ist aber bei allen Klassen so (siehe dein verlinktes PHP script) - bei "allen anderen" stimmt aber die Länge mit der Typendefinition im xsd und der Antwort aus dem SOAP request überein. Nur eben beim DomainObject nicht.


    Ich habe ja auch identifiziert, welche "zusätzliche" Info im Response steht. Das ist die (wie im CCP angezeigt) "Art" der Domain. (Ob "zusätzlich" oder Teil eines Hosting Pakets o.ä. - ich weiß nicht was da sonst noch stehen kann, ich hab nur 'zusätzliche' domains) - der Parameter ist aber nicht in der API beschrieben. Alle anderen Parameter mappen 1:1 (name, preis, renewal date, etc.)


    Ich schätze deine Hilfsbereitschaft, aber irgendwie verstehe ich dich nicht. Vielleicht drücke ich mich auch nicht gut aus.


    Grüße,

    Tom

  • Habe das Thema eben weitergegeben. Wir melden uns, wenn es dazu was Neues gibt. (Zur Info [netcup] Christina R.

    wie auch immer, ich habe etwas tiefer reingeschaut. Bis string authcode (nillable = TRUE, minoccurs = 1, maxoccurs = 1) scheint alles ok zu sein. Dann kommt lt. Beschreibung der string state (nillable = TRUE, minoccurs = 1, maxoccurs = 1) Domain can be inclusive or additional


    Das hängt in meiner Response ganz am Ende (siehe unten) und der String zwischen AuthCode und Registrycontacts registrycontacts (nillable = TRUE, minoccurs = 1, maxoccurs = 1)ist mit "unknown" beschrieben.


    Vielleicht verstehe ich aber auch was grundsätzlich nicht. Die Reihenfolge scheint sich je nach Inhalt zu verändern. Das ist schwierig, wenn man nur eine Liste bekommt und kein "dictionary". Wenn ich bspw. die DomainInfo einer gekündigten Domain hole, dann steht das Kündigungsdatum an der Stelle für das "cancellationrunning" flag (boolean) und im "deletiondate" steht weiterhin "unknown"(siehe alternative Blau)


    Inhalt von responseMessage['responsedata']['_value_1']


    [

    [0] 'myDomain.tld', # string domainname (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    [1] 'default nameservers', # Nameserverentries nameserverentry (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    [2] 'xxxxx', # positiveInteger customernumber (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    [3] { # Contactentries assignedcontacts (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    '_value_1': [

    xxxxxxx,

    xxxxxxx,

    xxxxxxx

    ],

    'id': None,

    'href': None,

    '_attr_1': {

    }

    },

    [4] 'FALSE', # boolean ownerchangerunning (nillable = FALSE, minoccurs = 1, maxoccurs = 1)

    [5] 'FALSE', (''20xx-xx-xx'') # boolean cancellationrunning (nillable = FALSE, minoccurs = 1, maxoccurs = 1)

    [6] '2022-xx-xx', # string nextbilling (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    [7] '12', # positiveInteger runtimemonths (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    [8] 'unknown', # string lastupdate (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    [9] 'unknown', # string domaincreated (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    [10] 'unknown', ( 'unknown'), # string deletiondate (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    [11] 'unknown', # string authcode (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    [12] 'unknown', # string state (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    [13] { # Registrycontacts registrycontacts (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    '_value_1': [

    'unknown',

    'unknown',

    'unknown',

    'unknown',

    'unknown',

    'unknown',

    'unknown',

    'unknown'

    ],

    'id': None,

    'href': None,

    '_attr_1': {

    }

    },

    [14] x.xx, # float priceperruntime (nillable = FALSE, minoccurs = 1, maxoccurs = 1)

    [15] 'publickey', # dnssectype dnssectype (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    [16] { # DnssecentriesObject dnssecentries (nillable = TRUE, minoccurs = 1, maxoccurs = 1)

    '_value_1': None,

    'arrayType': 'xsd:ur-type[0]',

    'offset': None,

    'id': None,

    'href': None,

    '_attr_1': {

    }

    },

    [17] 'additional domain' # ??? string state (nillable = TRUE, minoccurs = 1, maxoccurs = 1) ??? ]


    [netcup] Claudia H.

  • Wie sieht das ganze im Programm SoapUI aus? https://www.soapui.org/downloads/soapui/


    Bei benannten APIs kann die Reihenfolge abweichen - dafür sind die Felder im XML beschriftet.

    Eine Python Liste könnte dafür dann ungeeignet sein.


    Ggf. wurde der Python Client fehlerhaft implementiert.


    Versuche bei deinen Beiträgen bitte Code Blöcke zu verwenden - dann sind deine Beiträge besser lesbar.

  • Ich habe nicht herausgefunden, wie ich im Code Block Text farblich markieren kann, deshalb hatte ich es wieder entfernt. Sorry.

    Gern versuche ich mal zu beschreiben, wie ich die API benutze. (Ziemlich straight forward würde ich behaupten):


    Zur Kommunikation mit dem SOAP API endpoint benutze ich die zeep lib von python


    Den initialiesier ich wie folgt:

    Python
    import zeep
    from zeep.transports import Transport
    from zeep.plugins import HistoryPlugin
    
    transport = Transport()
    history = HistoryPlugin()
    
    client = zeep.Client(wsdl = 'https://ccp.netcup.net/run/webservice/servers/endpoint.php?WSDL', transport=transport, plugins=[history])


    Dann baue ich mir eine object aus der Typendefinition, die ich über den SOAP client erhalte, für das DomainObject bspw:


    Code
    Responsemessage = client.get_type('ns0:Responsemessage') # default
    
    DomainObject = client.get_type('ns0:DomainObject')


    Den Request mache ich dann ganz einfach über die ServiceProxy Instanz des zeep-clients: (session_id kommt vom login an der API - das erspare ich Dir hier)


    Code
    fct_call = getattr(client.service, 'infoDomain')
    response = fct_call(customernumber=c_id,apikey=api_key,apisessionid=session_id, clientrequestid=1, **params)

    mit **params:

    Code
    domainname=name,registryinformationflag=1

    Dann nehme ich die Antwort des API Enpoints und versuche damit mein "Typen-Object" zu initialisieren. Was zu 99% immer genau passt

    Dazu darf aber die Länge der Antwort (das ist eine Liste) nicht mehr Elemente haben, als das Object zur Initialisierung erwartet


    Code
    responseMessage = Responsemessage(*response['_value_1'])
    responseData = responseMessage['responsedata']['_value_1']
    
    myInfoDomain = DomainObject(*responseData) --> und hier liegt das Problem für "infoDomain": (TypeError: __init__() takes at most 17 positional arguments (18 given))

    Wenn alles passt bekomme ich im Normalfall ein Dictionary mit der gewünschten Struktur, wo ich dann auf die diversen Parameter per Name (key) zugreifen kann:


    Kein Rocket-Science...Und wie gesagt funktioniert für listallDomains, infoDnsRecord, infoHandle, listallHandle, createHandle, transferDomain, createDomain, updateDnsRecord usw. (fast) einwandfrei


    Grüße,

    Tom

  • Wo steht das denn für infoDomain? Finde das Mapping für den Aufruf nicht - nur an anderer Stelle.

    Nochmal: woher nimmst du die Info für den Typecast?


    Die Methode ListAllDomains hat dokumentiert: Responsemessage with information about result of the action like short and long resultmessages, message status, etc. Contains DomainObject objects in responsedata field.


    Die Methode infoDomain hat dokumentiert: Responsemessage with information about result of the action like short and long resultmessages, message status, etc.


    Aus der Doku ist überhaupt nicht ersichtlich, dass infoDomain ein DomainObject zurück liefert - woher nimmst du also diese Information.


    Im XML wird dieser "zusätzliche" Parameter so beschrieben, falls sich jemand wundert:

    Code
    <status xsi:type="xsd:string">additional domain</status>


    Generell sieht die SOAP Antwort für den infoDomain Call so aus:


  • Nochmal: woher nimmst du die Info für den Typecast?


    Komplett berechtige Frage. Aber ich hab's mir nicht selbst ausgedacht. Ich hab es gestern nicht mehr auf die schnelle gefunden aber ich suche nochmal.

    In der Doku steht nur "Contains DomainObject objects in responsedata field" für listallDomains - möglich, dass ich einfach davon ausgegangen bin, dass infoDomain auch ein (1) DomainObject dann zurückliefert, wenn listallDomains alle DomainObjects liefert.


    Wäre nicht unlogisch, imho.

    Tom


    Btw: in der Doku steht weder bei listallHandle oder infoHandle, dass die Response ein (oder mehrere) HandleObject(s) enthält, funktioniert aber bei beiden! :wacko: