Browse Source

HPCC-15141 Supports configurable NS base for ESDL ESP services

- Adds NS base configuration entry
- Allows url or urn based delimiters

Signed-off-by: rpastrana <rodrigo.pastrana@lexisnexis.com>
rpastrana 9 years ago
parent
commit
5ebe870566

+ 28 - 25
esp/services/esdl_svc_engine/esdl_binding.cpp

@@ -330,6 +330,15 @@ void EsdlServiceImpl::init(const IPropertyTree *cfg,
         }
         else
             ESPLOG(LogNormal, "ESP Service %s is not attached to any logging manager.", service);
+
+        m_usesURLNameSpace = false;
+        if (srvcfg->hasProp("@namespaceBase"))
+        {
+            m_serviceNameSpaceBase.set(srvcfg->queryProp("@namespaceBase")).trim();
+            m_usesURLNameSpace = startsWith(m_serviceNameSpaceBase.str(), "http://") ? true : false;
+        }
+        else
+            m_serviceNameSpaceBase.set(DEFAULT_ESDLBINDING_URN_BASE);
     }
     else
         throw MakeStringException(-1, "Could not access ESDL service configuration: esp process '%s' service name '%s'", process, service);
@@ -1184,9 +1193,6 @@ void EsdlBindingImpl::initEsdlServiceInfo(IEsdlDefService &srvdef)
             m_defaultSvcVersion.set(verstr);
     }
 
-    StringBuffer urn;
-    urn.appendf("%s:%s", ESDLBINDING_URN_BASE, srvdef.queryName());
-
     //superclass binding sets up wsdladdress
     //setWsdlAddress(bndcfg->queryProp("@wsdlServiceAddress"));
 
@@ -1382,25 +1388,19 @@ static bool getSoapMethodInfo(const char * xmlin,
     return false;
 }
 
-void parseNamespace(const char *ns,
-                    StringBuffer &service,
-                    StringBuffer &method,
-                    StringArray &opts,
-                    StringBuffer &version)
+void parseNamespace(const char *ns, StringBuffer &service, StringBuffer &method, StringArray &opts, StringBuffer &version, const char * namespacebase)
 {
-    //only handling soap requests from hpccsystems:ws ??
-    if (ns && !strnicmp(ns, ESDLBINDING_URN_BASE, 18))
+    if (ns && !strnicmp(ns, namespacebase, strlen(namespacebase)))
     {
-        //const char *str=ns+18;
-        const char *str=ns+strlen(ESDLBINDING_URN_BASE);
-        if (*str==':')
+        const char *str=ns+strlen(namespacebase);
+        if (*str==':' || *str=='/')
             str++;
-        while (*str && !strchr(":(@", *str))
+        while (*str && !strchr(":(@/", *str))
             service.append(*str++);
-        if (*str==':')
+        if (*str==':' || *str=='/')
         {
             str++;
-            while (*str && !strchr(":(@", *str))
+            while (*str && !strchr(":(@/", *str))
                 method.append(*str++);
             while (*str && !strchr("(@", *str))
                 str++;
@@ -1465,7 +1465,7 @@ int EsdlBindingImpl::HandleSoapRequest(CHttpRequest* request,
             StringBuffer nsver;
             StringArray nsopts;
 
-            parseNamespace(ns.str(), nssrv, nsmth, nsopts, nsver);
+            parseNamespace(ns.str(), nssrv, nsmth, nsopts, nsver, m_pESDLService->m_serviceNameSpaceBase.str());
 
             IProperties *qps=ctx->queryRequestParameters();
             if (nsopts.ordinality())
@@ -1590,15 +1590,18 @@ int EsdlBindingImpl::HandleSoapRequest(CHttpRequest* request,
     return 0;
 }
 
-StringBuffer &EsdlBindingImpl::generateNamespace(IEspContext &context,
-                                        CHttpRequest* request,
-                                        const char *serv,
-                                        const char *method,
-                                        StringBuffer &ns)
+StringBuffer & EsdlBindingImpl::generateNamespace(IEspContext &context, CHttpRequest* request, const char *serv, const char * method, StringBuffer & ns)
 {
-    ns.appendf("%s:%s", ESDLBINDING_URN_BASE, serv);
-    if (method && strlen(method) > 0)
-        ns.append(':').append(method);
+    if (m_pESDLService->m_serviceNameSpaceBase.length()>0)
+    {
+        ns.appendf("%s%c%s", m_pESDLService->m_serviceNameSpaceBase.str(), m_pESDLService->m_usesURLNameSpace ? '/' : ':', serv);
+
+        if (method && strlen(method) > 0)
+            ns.append(m_pESDLService->m_usesURLNameSpace ? '/': ':').append(method);
+    }
+    else
+        throw MakeStringExceptionDirect(-1, "Could not generate namespace, ensure namespace base is correctly configured.");
+
     StringBuffer ns_optionals;
     IProperties *params = context.queryRequestParameters();
     if (m_esdl)

+ 3 - 3
esp/services/esdl_svc_engine/esdl_binding.hpp

@@ -80,7 +80,6 @@ private:
 #endif
     Owned<IEmbedContext> javaplugin;
 
-
 public:
     StringBuffer                m_espServiceType;
     StringBuffer                m_espServiceName;
@@ -89,6 +88,8 @@ public:
     Owned<IPropertyTree>        m_pServiceMethodTargets;
     Owned<IEsdlTransformer>     m_pEsdlTransformer;
     Owned<IEsdlDefinition>      m_esdl;
+    StringBuffer                m_serviceNameSpaceBase;
+    bool                        m_usesURLNameSpace;
 
 public:
     IMPLEMENT_IINTERFACE;
@@ -168,8 +169,7 @@ public:
     void getSoapError(StringBuffer& out,StringBuffer& soapresp,const char *,const char *);
 };
 
-//RODRIGO: BASE URN should be configurable.
-#define ESDLBINDING_URN_BASE "urn:hpccsystems:ws"
+#define DEFAULT_ESDLBINDING_URN_BASE "urn:hpccsystems:ws"
 
 class EsdlBindingImpl : public CHttpSoapBinding
 {

+ 2 - 1
initfiles/componentfiles/configxml/@temp/esp_service_DynamicESDL.xsl

@@ -35,6 +35,7 @@
             </xsl:choose>
         </xsl:variable>
 
+        <xsl:variable name="namespaceBase" select="@namespaceBase"/>
         <xsl:variable name="serviceName" select="@name"/>
         <xsl:variable name="bindName" select=" $bindingNode/@name"/>
         <xsl:variable name="bindType">
@@ -53,7 +54,7 @@
                 <xsl:with-param name="plugin" select="Properties/@plugin"/>
             </xsl:call-template>
         </xsl:variable>
-        <EspService name="{$serviceName}" type="{$serviceType}" plugin="{$servicePlugin}">
+        <EspService name="{$serviceName}" type="{$serviceType}" plugin="{$servicePlugin}" namespaceBase="{$namespaceBase}">
             <xsl:if test="string(@LoggingManager) != ''">
                 <xsl:variable name="managerName" select="@LoggingManager"/>
                 <xsl:variable name="managerNode" select="/Environment/Software/LoggingManager[@name=$managerName]"/>

+ 8 - 0
initfiles/componentfiles/configxml/esdlsvcengine.xsd

@@ -35,6 +35,14 @@
                     </xs:appinfo>
                 </xs:annotation>
             </xs:attribute>
+            <xs:attribute name="namespaceBase" type="xs:string" use="optional" default="urn:hpccsystems:ws">
+                <xs:annotation>
+                    <xs:appinfo>
+                        <title>ESDL service namespace base</title>
+                        <tooltip>Overrides default urn for this ESDL service</tooltip>
+                    </xs:appinfo>
+                </xs:annotation>
+            </xs:attribute>
             <xs:attribute name="LoggingManager" type="loggingmanagerType" use="optional">
                 <xs:annotation>
                     <xs:appinfo>

+ 1 - 1
tools/esdlcmd/esdlcmd_common.hpp

@@ -77,7 +77,7 @@ typedef IEsdlCommand *(*EsdlCommandFactory)(const char *cmdname);
 
 #define ESDLOPT_WSDL_ADDRESS            "--wsdl-address"
 
-#define ESDLBINDING_URN_BASE            "urn:hpccsystems:ws"
+#define DEFAULT_NAMESPACE_BASE          "urn:hpccsystems:ws"
 #define ESDLOPTLIST_DELIMITER           ";"
 
 #define ESDL_OPT_SERVICE_SERVER         "-s"

+ 7 - 3
tools/esdlcmd/esdlcmd_core.cpp

@@ -187,7 +187,7 @@ public:
 
         if(optTargetNamespace.isEmpty())
         {
-            optTargetNamespace.set(ESDLBINDING_URN_BASE);
+            optTargetNamespace.set(DEFAULT_NAMESPACE_BASE);
         }
 
         return true;
@@ -385,10 +385,14 @@ public:
 
     StringBuffer & generateNamespace(StringBuffer &ns)
     {
-       ns.appendf("%s:%s", optTargetNamespace.get(), optService.get());
+        bool urlNamespace = false;
+        if (startsWith(optTargetNamespace.get(), "http://"))
+            urlNamespace = true;
+
+       ns.appendf("%s%c%s", optTargetNamespace.get(), urlNamespace ? '/' : ':', optService.get());
        //only add methodname if single method used.
        if (!optMethod.isEmpty() && !strstr(optMethod.get(), ESDLOPTLIST_DELIMITER))
-           ns.append(':').append(optMethod.get());
+           ns.append(urlNamespace ? '/' : ':').append(optMethod.get());
 
        //todo
        /*