Browse Source

HPCC-17178 Allow setting of timeouts for ESDL generated c++ soap clients

Signed-off-by: Anthony Fishbeck <anthony.fishbeck@lexisnexis.com>
Anthony Fishbeck 8 years ago
parent
commit
afce0f3f86

+ 6 - 0
esp/bindings/SOAP/Platform/soapbind.cpp

@@ -225,7 +225,13 @@ void CSoapRequestBinding::post(const char *proxy, const char* url, IRpcResponseB
     serialize(*static_cast<IRpcMessage*>(&rpccall));
     
     CSoapClient soapclient; //to add support for handling cookies soapclient(false);
+    if (connectTimeoutMs_)
+        soapclient.setConnectTimeoutMs(connectTimeoutMs_);
+    if (readTimeoutSecs_)
+        soapclient.setReadTimeoutSecs(readTimeoutSecs_);
+
     soapclient.setUsernameToken(getUserId(), getPassword(), getRealm());
+
     int result = soapclient.postRequest(soapaction, rpccall, rpcresponse);
 
     if(result == SOAP_OK)

+ 10 - 1
esp/bindings/SOAP/Platform/soapbind.hpp

@@ -125,7 +125,8 @@ public:
 
 class esp_http_decl CSoapRequestBinding : public CSoapComplexType,
     implements IRpcRequestBinding,
-    implements IEspRequest
+    implements IEspRequest,
+    implements IEspClientRpcSettings
 {
 private:
     StringBuffer url_;
@@ -133,6 +134,8 @@ private:
     StringBuffer userid_;
     StringBuffer password_;
     StringBuffer realm_;
+    unsigned connectTimeoutMs_ = 0;
+    unsigned readTimeoutSecs_ = 0;
 
 public:
     IMPLEMENT_IINTERFACE;
@@ -148,6 +151,12 @@ public:
     void setThunkHandle(void * val){thunk_=val;}
     void * getThunkHandle(){return thunk_;}
 
+    void setConnectTimeOutMs(unsigned timeout) override {connectTimeoutMs_ = timeout;}
+    unsigned getConnectTimeOutMs() override {return connectTimeoutMs_;}
+
+    void setReadTimeOutSecs(unsigned timeout) override {readTimeoutSecs_ = timeout;}
+    unsigned getReadTimeOutSecs() override {return readTimeoutSecs_;}
+
     void setUrl(const char *url){url_.clear().append(url);} 
     const char * getUrl(){return url_.str();}
 

+ 8 - 3
esp/bindings/SOAP/client/soapclient.cpp

@@ -153,11 +153,9 @@ int CSoapClient::postRequest(const char* contenttype, const char* soapaction, IR
     if(m_transportclient.get() == NULL)
     {
         Owned<IHttpClientContext> httpctx = getHttpClientContext();
-        IHttpClient* httpclient = httpctx->createHttpClient(call->getProxy(), call->get_url());
-        m_transportclient.setown(httpclient);
+        Owned<IHttpClient> httpclient = httpctx->createHttpClient(call->getProxy(), call->get_url());
         if (m_disableKeepAlive)
             httpclient->disableKeepAlive();
-
         if(m_username.length() > 0)
         {
             httpclient->setUserID(m_username.get());
@@ -167,6 +165,13 @@ int CSoapClient::postRequest(const char* contenttype, const char* soapaction, IR
         {
             httpclient->setRealm(m_realm.get());
         }
+
+        if (m_connectTimeoutMs)
+            httpclient->setConnectTimeOutMs(m_connectTimeoutMs);
+        if (m_readTimeoutSecs)
+            httpclient->setTimeOut(m_readTimeoutSecs);
+
+        m_transportclient.setown(httpclient.getClear());
     }
 
     if (!soap_request.get() || !soap_response.get())

+ 18 - 0
esp/bindings/SOAP/client/soapclient.hpp

@@ -27,6 +27,7 @@
 
 //ESP Bindings
 #include "SOAP/Platform/soapmessage.hpp"
+#include "http/client/httpclient.hpp"
 
 class esp_http_decl CSoapClient : implements ISoapClient, public CInterface
 {
@@ -36,6 +37,9 @@ private:
     StringAttr                  m_realm;
     bool                        m_disableKeepAlive;
     Owned<ITransportClient> m_transportclient;
+    unsigned m_connectTimeoutMs = 0;
+    unsigned m_readTimeoutSecs = 0;
+
     int postRequest(const char* contenttype, const char* soapaction, IRpcMessage& rpccall, 
                          StringBuffer& responsebuf, CMimeMultiPart* resp_multipart, IRpcMessageArray *headers=NULL);
 
@@ -45,6 +49,20 @@ public:
     CSoapClient(){m_disableKeepAlive=false;}
     CSoapClient(ITransportClient* transportclient){m_transportclient.setown(transportclient); m_disableKeepAlive=false;}
     virtual ~CSoapClient() {};
+
+    void setConnectTimeoutMs(unsigned val)
+    {
+        m_connectTimeoutMs = val;
+        if (m_transportclient)
+            static_cast<IHttpClient*>(m_transportclient.get())->setConnectTimeOutMs(m_connectTimeoutMs); //until we support something other than soap over http, static_cast
+    }
+    void setReadTimeoutSecs(unsigned val)
+    {
+        m_readTimeoutSecs = val;
+        if (m_transportclient)
+            static_cast<IHttpClient*>(m_transportclient.get())->setTimeOut(m_readTimeoutSecs); //until we support something other than soap over http, static_cast
+    }
+
     virtual int setUsernameToken(const char* userid, const char* password, const char* realm);
     virtual void disableKeepAlive() { m_disableKeepAlive = true;}
 

+ 17 - 13
esp/bindings/http/client/httpclient.cpp

@@ -37,7 +37,6 @@
      CHttpClient Implementation
 **************************************************************************/
 #define URL_MAX  512
-#define HTTP_CLIENT_DEFAULT_CONNECT_TIMEOUT 3000
 
 CHttpClientContext::CHttpClientContext()
 {
@@ -122,7 +121,7 @@ IHttpClient* CHttpClientContext::createHttpClient(const char* proxy, const char*
 
 
 
-CHttpClient::CHttpClient(const char *proxy, const char* url) : m_proxy(proxy), m_url(url), m_disableKeepAlive(false), m_timeout(0)
+CHttpClient::CHttpClient(const char *proxy, const char* url) : m_proxy(proxy), m_url(url), m_disableKeepAlive(false)
 {
     StringBuffer protocol,username,password, host, port, path;
     Utils::SplitURL(url, protocol,username,password, host, port, path);
@@ -184,9 +183,14 @@ void CHttpClient::setProxy(const char* proxy)
     m_proxy.clear().append(proxy);
 }
 
+void CHttpClient::setConnectTimeOutMs(unsigned timeout)
+{
+    m_connectTimeoutMs =  timeout;
+}
+
 void CHttpClient::setTimeOut(unsigned int timeout)
 {
-    m_timeout =  timeout;
+    m_readTimeoutSecs =  timeout;
 }
 
 int CHttpClient::connect(StringBuffer& errmsg)
@@ -222,10 +226,7 @@ int CHttpClient::connect(StringBuffer& errmsg)
 
     try
     {
-        if(m_timeout)
-            m_socket = ISocket::connect_timeout(ep,m_timeout);
-        else
-            m_socket = ISocket::connect_timeout(ep, HTTP_CLIENT_DEFAULT_CONNECT_TIMEOUT);
+        m_socket = ISocket::connect_timeout(ep, m_connectTimeoutMs);
 
         if(strcmp(m_protocol.get(), "HTTPS") == 0)
         {
@@ -342,10 +343,10 @@ int CHttpClient::sendRequest(const char* method, const char* contenttype, String
     }
 #endif
 
-    if(m_timeout)
-        httpresponse->setTimeOut(m_timeout);
-
     httprequest->send();
+
+    if (m_readTimeoutSecs)
+        httpresponse->setTimeOut(m_readTimeoutSecs);
     httpresponse->receive(false, NULL);  // MORE - pass in IMultiException if we want to see exceptions (which are not fatal)
 
 #ifdef COOKIE_HANDLING
@@ -462,10 +463,10 @@ int CHttpClient::sendRequest(IProperties *headers, const char* method, const cha
     }
 #endif
 
-    if(m_timeout)
-        httpresponse->setTimeOut(m_timeout);
-
     httprequest->send();
+
+    if (m_readTimeoutSecs)
+        httpresponse->setTimeOut(m_readTimeoutSecs);
     httpresponse->receive(alwaysReadContent, me);  // MORE - pass in IMultiException if we want to see exceptions (which are not fatal)
 
 #ifdef COOKIE_HANDLING
@@ -638,6 +639,9 @@ int CHttpClient::postRequest(ISoapMessage &req, ISoapMessage& resp)
 #endif
     httprequest->send();
     Owned<IMultiException> me = MakeMultiException();
+
+    if (m_readTimeoutSecs)
+        httpresponse->setTimeOut(m_readTimeoutSecs);
     httpresponse->receive(true, me);
 
 #ifdef COOKIE_HANDLING

+ 3 - 0
esp/bindings/http/client/httpclient.hpp

@@ -21,12 +21,15 @@
 #include "esphttp.hpp"
 #include "soapesp.hpp"
 
+#define HTTP_CLIENT_DEFAULT_CONNECT_TIMEOUT 3000
+
 interface IHttpClient : extends ITransportClient
 {
     virtual void setProxy(const char* proxy) = 0;
     virtual void setUserID(const char* userid) = 0;
     virtual void setPassword(const char* password) = 0;
     virtual void setRealm(const char* realm) = 0;
+    virtual void setConnectTimeOutMs(unsigned timeout) = 0;
     virtual void setTimeOut(unsigned int timeout) = 0;
     virtual void disableKeepAlive() = 0;
 

+ 4 - 1
esp/bindings/http/client/httpclient.ipp

@@ -92,7 +92,9 @@ private:
     StringBuffer m_proxy;
     ISocket*   m_socket;
     bool          m_disableKeepAlive;
-    unsigned int m_timeout;
+
+    unsigned m_connectTimeoutMs = HTTP_CLIENT_DEFAULT_CONNECT_TIMEOUT;
+    unsigned m_readTimeoutSecs = 0;
 
     StringAttr m_userid;
     StringAttr m_password;
@@ -120,6 +122,7 @@ public:
     virtual void setUserID(const char* userid);
     virtual void setPassword(const char* password);
     virtual void setRealm(const char* realm);
+    virtual void setConnectTimeOutMs(unsigned timeout) override;
     virtual void setTimeOut(unsigned int timeout);
 };
 

+ 8 - 1
esp/scm/esp.ecm

@@ -239,6 +239,14 @@ SCMinterface IEspRequest(IEspStruct)
 {
 };
 
+SCMinterface IEspClientRpcSettings(IEspStruct)
+{
+    void setConnectTimeOutMs(unsigned val);
+    unsigned getConnectTimeOutMs();
+
+    void setReadTimeOutSecs(unsigned val);
+    unsigned getReadTimeOutSecs();
+};
 
 SCMinterface IEspResponse(IEspStruct)
 {
@@ -247,7 +255,6 @@ SCMinterface IEspResponse(IEspStruct)
     void  noteException(IException& e);
 };
 
-
 SCMinterface IEspService(IInterface)
 {
     const char * getServiceType();

+ 4 - 0
tools/hidl/hidlcomp.cpp

@@ -3153,6 +3153,9 @@ void EspMessageInfo::write_esp_ipp()
         outf("\n\tC%s(IEspContext* ctx, const char *serviceName, IProperties *params, MapStrToBuf *attachments);", name_);
     }   
 
+    if (espm_type_==espm_request)
+        outs("\n\tIEspClientRpcSettings &rpc(){return *static_cast<IEspClientRpcSettings*>(this);}\n\n");
+
     outf("\n\tvirtual const char *getNsURI(){return %s;}\n", getMetaString("ns_uri", "NULL"));
     outf("\n\tvirtual const char *getNsPrefix(){return %s;}\n", getMetaString("ns_var", "NULL"));
     outs("\n\tvirtual const char *getRootName(){return m_msgName.str();}\n");
@@ -5224,6 +5227,7 @@ void EspMessageInfo::write_cpp_interfaces()
     switch (espm_type_)
     {
     case espm_request:
+        outs("\n\tvirtual IEspClientRpcSettings &rpc() = 0;\n\n");
         write_esp_methods(espaxm_setters, true, true);
         write_esp_mapinfo(true);
         break;