2010-03-25 10 views
6

Quando provo a collegarmi a un servizio Web MS CRM usando suds/python-ntlm, ricevo un timeout sulle richieste. Tuttavia, il codice che sto tentando di sostituire - che richiama l'app della riga di comando cURL per fare la stessa chiamata - ha successo.Perché si verifica un errore/timeout della connessione quando si utilizza python suds per connettersi a Microsoft CRM?

Chiaramente qualcosa è diverso nel modo in cui CURL invia i dati di comando, ma sarei dannato se so qual è la differenza. Di seguito sono riportati i dettagli completi delle varie chiamate. Qualcuno ha qualche consiglio?

Ecco il codice che sta effettuando la richiesta, seguito dall'output. Il codice comando cURL è inferiore a quello e segue la sua risposta. Host, utenti e password sono stati modificati per proteggere gli innocenti, ovviamente.

wsdl_url = 'https://client.service.host/MSCrmServices/2007/MetadataService.asmx?WSDL' 
username = r'domain\user.name' 
password = 'userpass' 

from suds.transport.https import WindowsHttpAuthenticated 
from suds.client import Client 

import logging 
logging.basicConfig(level=logging.INFO) 
logging.getLogger('suds.client').setLevel(logging.DEBUG) 
logging.getLogger('suds.transport').setLevel(logging.DEBUG) 

ntlmTransport = WindowsHttpAuthenticated(username=username, password=password) 
metadata_client = Client(wsdl_url, transport=ntlmTransport) 

request = metadata_client.factory.create('RetrieveAttributeRequest') 
request.MetadataId = '00000000-0000-0000-0000-000000000000' 
request.EntityLogicalName = 'opportunity' 
request.LogicalName = 'new_typeofcontact' 
request.RetrieveAsIfPublished = 'false' 

attr = metadata_client.service.Execute(request) 
print attr 

ecco l'output:

DEBUG:suds.client:sending to (http://client.service.host/MSCrmServices/2007/MetadataService.asmx) 
message: 
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/crm/2007/WebServices" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <SOAP-ENV:Header/> 
    <ns0:Body> 
     <ns1:Execute> 
     <ns1:Request xsi:type="ns1:RetrieveAttributeRequest"> 
      <ns1:MetadataId>00000000-0000-0000-0000-000000000000</ns1:MetadataId> 
      <ns1:EntityLogicalName>opportunity</ns1:EntityLogicalName> 
      <ns1:LogicalName>new_typeofcontact</ns1:LogicalName> 
      <ns1:RetrieveAsIfPublished>false</ns1:RetrieveAsIfPublished> 
     </ns1:Request> 
     </ns1:Execute> 
    </ns0:Body> 
</SOAP-ENV:Envelope> 
DEBUG:suds.client:headers = {'SOAPAction': u'"http://schemas.microsoft.com/crm/2007/WebServices/Execute"', 'Content-Type': 'text/xml'} 
DEBUG:suds.transport.http:sending: 
URL:http://client.service.host/MSCrmServices/2007/MetadataService.asmx 
HEADERS: {'SOAPAction': u'"http://schemas.microsoft.com/crm/2007/WebServices/Execute"', 'Content-Type': 'text/xml', 'Content-type': 'text/xml', 'Soapaction': u'"http://schemas.microsoft.com/crm/2007/WebServices/Execute"'} 
MESSAGE: 
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/crm/2007/WebServices" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <SOAP-ENV:Header/> 
    <ns0:Body> 
     <ns1:Execute> 
     <ns1:Request xsi:type="ns1:RetrieveAttributeRequest"> 
      <ns1:MetadataId>00000000-0000-0000-0000-000000000000</ns1:MetadataId> 
      <ns1:EntityLogicalName>opportunity</ns1:EntityLogicalName> 
      <ns1:LogicalName>new_typeofcontact</ns1:LogicalName> 
      <ns1:RetrieveAsIfPublished>false</ns1:RetrieveAsIfPublished> 
     </ns1:Request> 
     </ns1:Execute> 
    </ns0:Body> 
</SOAP-ENV:Envelope> 
ERROR: An unexpected error occurred while tokenizing input 
The following traceback may be corrupted or invalid 
The error message is: ('EOF in multi-line statement', (16, 0)) 

--------------------------------------------------------------------------- 
URLError         Traceback (most recent call last) 

/Users/crose/projects/2366/crm/<ipython console> in <module>() 

/var/folders/nb/nbJAzxR1HbOppPcs6xO+dE+++TY/-Tmp-/python-67186icm.py in <module>() 
    19 request.LogicalName = 'new_typeofcontact' 
    20 request.RetrieveAsIfPublished = 'false' 
    21 
---> 22 attr = metadata_client.service.Execute(request) 
    23 print attr 

/Users/crose/virtualenv/advanis/lib/python2.6/site-packages/suds/client.pyc in __call__(self, *args, **kwargs) 
    537     return (500, e) 
    538   else: 
--> 539    return client.invoke(args, kwargs) 
    540   
    541  def faults(self): 

/Users/crose/virtualenv/advanis/lib/python2.6/site-packages/suds/client.pyc in invoke(self, args, kwargs) 
    596     self.method.name, timer) 
    597   timer.start() 
--> 598   result = self.send(msg) 
    599   timer.stop() 
    600   metrics.log.debug(

/Users/crose/virtualenv/advanis/lib/python2.6/site-packages/suds/client.pyc in send(self, msg) 
    621    request = Request(location, str(msg)) 
    622    request.headers = self.headers() 
--> 623    reply = transport.send(request) 
    624    if retxml: 
    625     result = reply.message 

/Users/crose/virtualenv/advanis/lib/python2.6/site-packages/suds/transport/https.pyc in send(self, request) 
    62  def send(self, request): 
    63   self.addcredentials(request) 
---> 64   return HttpTransport.send(self, request) 
    65  
    66  def addcredentials(self, request): 

/Users/crose/virtualenv/advanis/lib/python2.6/site-packages/suds/transport/http.pyc in send(self, request) 
    75    request.headers.update(u2request.headers) 
    76    log.debug('sending:\n%s', request) 
---> 77    fp = self.u2open(u2request) 
    78    self.getcookies(fp, u2request) 
    79    result = Reply(200, fp.headers.dict, fp.read()) 

/Users/crose/virtualenv/advanis/lib/python2.6/site-packages/suds/transport/http.pyc in u2open(self, u2request) 
    116    return url.open(u2request) 
    117   else: 
--> 118    return url.open(u2request, timeout=tm) 
    119    
    120  def u2opener(self): 

/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.pyc in open(self, fullurl, data, timeout) 
    381    req = meth(req) 
    382 
--> 383   response = self._open(req, data) 
    384 
    385   # post-process response 

/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.pyc in _open(self, req, data) 
    399   protocol = req.get_type() 
    400   result = self._call_chain(self.handle_open, protocol, protocol + 
--> 401         '_open', req) 
    402   if result: 
    403    return result 

/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.pyc in _call_chain(self, chain, kind, meth_name, *args) 
    359    func = getattr(handler, meth_name) 
    360 
--> 361    result = func(*args) 
    362    if result is not None: 
    363     return result 

/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.pyc in http_open(self, req) 
    1128 
    1129  def http_open(self, req): 
-> 1130   return self.do_open(httplib.HTTPConnection, req) 
    1131 
    1132  http_request = AbstractHTTPHandler.do_request_ 

/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.pyc in do_open(self, http_class, req) 
    1103    r = h.getresponse() 
    1104   except socket.error, err: # XXX what error? 
-> 1105    raise URLError(err) 
    1106 
    1107   # Pick apart the HTTPResponse object to get the addinfourl 

URLError: <urlopen error [Errno 60] Operation timed out> 

Il comando cURL è:

/opt/local/bin/curl --ntlm -u "domain\user.name:userpass" -k -d @- -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; InfoPath.1)" -H "Connection: Keep-Alive" -H "Content-Type: text/xml; charset=utf-8" -H "SOAPAction: http://schemas.microsoft.com/crm/2007/WebServices/Execute" https://client.service.host/MSCrmServices/2007/MetadataService.asmx 

I dati che il piping a questo comando cURL:

 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
      <soap:Header> 
       <CrmAuthenticationToken xmlns="http://schemas.microsoft.com/crm/2007/WebServices"> 
        <AuthenticationType xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes">0</AuthenticationType> 
        <CrmTicket xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes"></CrmTicket> 
        <OrganizationName xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes">CMIFS</OrganizationName> 
        <CallerId xmlns="http://schemas.microsoft.com/crm/2007/CoreTypes">00000000-0000-0000-0000-000000000000</CallerId> 
       </CrmAuthenticationToken> 
      </soap:Header> 


     <soap:Body> 
      <Execute xmlns="http://schemas.microsoft.com/crm/2007/WebServices"> 
       <Request xsi:type="RetrieveAttributeRequest"> 
        <MetadataId>00000000-0000-0000-0000-000000000000</MetadataId> 
        <EntityLogicalName>opportunity</EntityLogicalName> 
        <LogicalName>new_typeofcontact</LogicalName> 
        <RetrieveAsIfPublished>false</RetrieveAsIfPublished> 
       </Request> 
      </Execute> 
     </soap:Body> 


     </soap:Envelope> 

Ecco la risposta :

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <soap:Body> 
    <ExecuteResponse 
    xmlns="http://schemas.microsoft.com/crm/2007/WebServices"> 
     <Response xsi:type="RetrieveAttributeResponse"> 
     <AttributeMetadata xsi:type="PicklistAttributeMetadata"> 
      <MetadataId>101346cf-a6af-4eb4-a4bf-9c3c6bbd6582</MetadataId> 
      <SchemaName>New_TypeofContact</SchemaName> 
      <LogicalName>new_typeofcontact</LogicalName> 
      <EntityLogicalName>opportunity</EntityLogicalName> 
      <AttributeType> 
      <Value>Picklist</Value> 
      </AttributeType> 
      <!-- stuff here --> 
     </AttributeMetadata> 
     </Response> 
    </ExecuteResponse> 
    </soap:Body> 
</soap:Envelope> 
+1

Un po 'di più: sembra che la chiamata stia ricevendo una seconda risposta 401 non autorizzata, ma il gestore è sospeso in risposta ad esso, in attesa di una risposta che non arriva mai. È strano perché le stesse credenziali sono state utilizzate con successo, non un decimo di secondo prima, per recuperare il file WSDL dal WSDL dell'endpoint. Qualsiasi opinione che la gente possa offrire qui sarebbe molto gradita. –

risposta

4

Sembra che si possa avere un problema con la posizione nel WSDL. Se si controlla l'output di debug quando si dice che sta inviando:

DEBUG:suds.transport.http:sending: 
URL:http://client.service.host/MSCrmServices/2007/MetadataService.asmx 

Nota che l'URL è http, e che non vibe con la connessione iniziale, che era https.

provare a modificare l'istanza del cliente con l'aggiunta di un argomento posizione per forzarlo l'utilizzo di HTTPS in questo modo:

svc_url = 'https://client.service.host/MSCrmServices/2007/MetadataService.asmx' 
metadata_client = Client(wsdl_url, transport=ntlmTransport, location=svc_url) 

(Si noti che l'URL del servizio dovrebbe essere lo stesso di come URL WSDL meno il ?WSDL).

+0

Ho provato anche quello; questa è la prima cosa che ho notato, mi spiace che la domanda non lo rispecchi. –

+0

Ti dispiacerebbe postare l'output della parte '' del WSDL? Dovrebbe essere in fondo ed è la parte che contiene la posizione predefinita. – jathanism

0
svc_url = 'https://client.service.host/MSCrmServices/2007/MetadataService.asmx' 
metadata_client = Client(wsdl_url, transport=ntlmTransport, location=svc_url, cache=None) 

L'aggiunta di cache=None in realtà fa il trucco.