Quellcode durchsuchen

Merge pull request #11162 from rpastrana/HPCC-HPCC-19679-ReportHistory

HPCC-19679 Report ESDL Binding and Definition History

Reviewed-By: Yanrui Ma <yanrui.ma@lexisnexisrisk.com>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman vor 7 Jahren
Ursprung
Commit
22d4e94878

+ 31 - 9
esp/scm/ws_esdlconfig.ecm

@@ -33,12 +33,28 @@ ESPStruct ESDLConfiguration
 {
     ESParray<ESPStruct MethodConfig, Method> Methods;
 };
+
+ESPstruct PublishHistory
+{
+    string PublishBy;
+    string CreatedTime;
+    string LastEditBy;
+    string LastEditTime;
+};
+
 ESPstruct ESDLBinding
 {
     string Id;
     string EspProcess;
     [min_ver("1.4")] int Port;
     [max_ver("1.3")] string EspBinding;
+    [min_ver("1.4")] ESPStruct PublishHistory History;
+};
+
+ESPstruct ESDLService
+{
+    ESParray<ESPStruct MethodConfig, Method> Methods;
+    String Name;
 };
 
 ESPstruct ESDLDefinition
@@ -47,13 +63,17 @@ ESPstruct ESDLDefinition
     int Seq;
     string Id;
     [min_ver("1.1")] string Interface;
-    [min_ver("1.2")] ESParray<string, Name> ESDLServices;
+    [min_ver("1.2"), max_ver("1.3")] ESParray<string, Name> ESDLServices;
+    [min_ver("1.4")] ESParray<ESPStruct ESDLService, Service> Services;
+    [min_ver("1.4")] ESPStruct PublishHistory History;
 };
 
+//ESPStruct ESDLBindingContents : ESDLBinding
 ESPStruct ESDLBindingContents
 {
     ESPStruct ESDLDefinition Definition;
     ESPStruct ESDLConfiguration Configuration;
+    [min_ver("1.4")] ESPStruct PublishHistory History;
 };
 
 ESPrequest [nil_remove] GetESDLDefinitionRequest
@@ -67,11 +87,13 @@ ESPrequest [nil_remove] GetESDLDefinitionRequest
 
 ESPresponse [nil_remove, exceptions_inline] GetESDLDefinitionResponse
 {
-    string Id;
-    [min_ver("1.2")] ESParray<string, Name> ESDLServices;
-    string XMLDefinition;
+    [max_ver("1.3")] string Id; //moves to definition struct
+    [min_ver("1.2"), max_ver("1.3")] ESParray<string, Name> ESDLServices; //moves to definition struct
+    [max_ver("1.3")] string XMLDefinition; //moves to definition struct as Interface
     ESPstruct BaseESDLStatus status;
-    ESParray<ESPStruct MethodConfig, Method> Methods;
+    [max_ver("1.3")] ESParray<ESPStruct MethodConfig, Method> Methods; //moves to definition/services/service
+
+    [min_ver("1.4")] ESPStruct ESDLDefinition Definition;
 };
 
 ESPrequest PublishESDLDefinitionRequest
@@ -88,9 +110,10 @@ ESPresponse [nil_remove, exceptions_inline] PublishESDLDefinitionResponse
     int EsdlVersion;
     boolean DeletePrevious;
     ESPstruct BaseESDLStatus status;
-    [min_ver("1.2")] ESParray<string, Name> ESDLServices;
-    [min_ver("1.2")] string XMLDefinition;
-    [min_ver("1.2")] ESParray<ESPStruct MethodConfig, Method> Methods;
+    [min_ver("1.2"), max_ver("1.3")] ESParray<string, Name> ESDLServices; //moves to definition struct
+    [min_ver("1.2"), max_ver("1.3")] string XMLDefinition; //moves to definition struct as Interface
+    [min_ver("1.2"), max_ver("1.3")] ESParray<ESPStruct MethodConfig, Method> Methods; //moves to definition/services/service
+    [min_ver("1.4")] ESPStruct ESDLDefinition Definition;
 };
 
 ESPrequest [nil_remove] PublishESDLBindingRequest
@@ -260,7 +283,6 @@ ESPresponse [exceptions_inline] ListESDLBindingsResponse
 };
 
 #define VERSION_FOR_ESDLCMD "1.4"
-
 ESPservice [auth_feature("ESDLConfigAccess:ACCESS"), version("1.4"), exceptions_inline("./smc_xslt/exceptions.xslt")] WsESDLConfig
 {
     ESPmethod Echo(EchoRequest, EchoResponse);

+ 1 - 1
esp/services/esdl_svc_engine/esdl_binding.cpp

@@ -1050,7 +1050,7 @@ bool EsdlBindingImpl::loadDefinitions(const char * espServiceName, Owned<IEsdlDe
             else
                 PROGLOG("Esdl definition %s not found in shared cache, loading it from store", id);
             StringBuffer esdlXML;
-            m_pCentralStore->fetchDefinition(id, esdlXML);
+            m_pCentralStore->fetchDefinitionXML(id, esdlXML);
             if (!esdlXML.length())
             {
                 Owned<IPropertyTree> esdlDefintion;

+ 48 - 2
esp/services/esdl_svc_engine/esdl_store.cpp

@@ -52,7 +52,53 @@ public:
     }
     virtual ~CEsdlSDSStore() { }
 
-    virtual void fetchDefinition(const char* definitionId, StringBuffer& esxdl) override
+    virtual IPropertyTree* fetchDefinition(const char* definitionId) override
+    {
+        if (!definitionId || !*definitionId)
+            throw MakeStringException(-1, "Unable to fetch ESDL Service definition information, definition id is not available");
+
+        if (!strchr (definitionId, '.')) //no name.ver delimiter, find latest version of name
+        {
+            Owned<IRemoteConnection> conn = querySDS().connect(ESDL_DEFS_ROOT_PATH, myProcessSession(), RTM_LOCK_READ, SDS_LOCK_TIMEOUT_DESDL);
+            if (!conn)
+                throw MakeStringException(-1, "Unable to connect to ESDL Service definition information in dali '%s'", ESDL_DEFS_ROOT_PATH);
+
+            IPropertyTree * esdlDefinitions = conn->queryRoot();
+
+            if (esdlDefinitions)
+            {
+                VStringBuffer xpath("%s[@name='%s']", ESDL_DEF_ENTRY, definitionId);
+                Owned<IPropertyTreeIterator> iter = esdlDefinitions->getElements(xpath.str());
+
+                unsigned latestSeq = 1;
+                ForEach(*iter)
+                {
+                    IPropertyTree &item = iter->query();
+                    unsigned thisSeq = item.getPropInt("@seq");
+                    if (thisSeq > latestSeq)
+                        latestSeq = thisSeq;
+                }
+                xpath.setf("%s[@id='%s.%d'][1]", ESDL_DEF_ENTRY, definitionId, latestSeq);
+                DBGLOG("ESDL Binding: Fetching ESDL Definition '%s.%d' from Dali", definitionId, latestSeq);
+                return esdlDefinitions->getPropTree(xpath);
+            }
+            else
+                throw MakeStringException(-1, "Unable to fetch ESDL definition '%s' from dali", definitionId);
+        }
+        else
+        {
+            //There shouldn't be multiple entries here, but if so, we'll use the first one
+            VStringBuffer xpath("%s[@id='%s'][1]", ESDL_DEF_PATH, definitionId);
+            Owned<IRemoteConnection> conn = querySDS().connect(xpath.str(), myProcessSession(), RTM_LOCK_READ, SDS_LOCK_TIMEOUT_DESDL);
+            if (!conn)
+             throw MakeStringException(-1, "Unable to connect to ESDL Service definition information in dali '%s'", xpath.str());
+
+             return createPTreeFromIPT(conn->queryRoot());
+        }
+        return nullptr;
+    }
+
+    virtual void fetchDefinitionXML(const char* definitionId, StringBuffer& esxdl) override
     {
         if (!definitionId || !*definitionId)
             throw MakeStringException(-1, "Unable to fetch ESDL Service definition information, definition id is not available");
@@ -68,7 +114,7 @@ public:
         toXML(conn->queryRoot(), esxdl, 0, 0);
     }
 
-    virtual void fetchLatestDefinition(const char* definitionName, StringBuffer& esxdl) override
+    virtual void fetchLatestDefinitionXML(const char* definitionName, StringBuffer& esxdl) override
     {
         if (!definitionName || !*definitionName)
             throw MakeStringException(-1, "Unable to fetch ESDL Service definition information, definition name is not available");

+ 3 - 2
esp/services/esdl_svc_engine/esdl_store.hpp

@@ -30,8 +30,9 @@
 
 interface IEsdlStore : public IInterface
 {
-    virtual void fetchDefinition(const char* definitionId, StringBuffer& esxdl) = 0;
-    virtual void fetchLatestDefinition(const char* definitionName, StringBuffer& esxdl) = 0;
+    virtual IPropertyTree* fetchDefinition(const char* definitionId) = 0;
+    virtual void fetchDefinitionXML(const char* definitionId, StringBuffer& esxdl) = 0;
+    virtual void fetchLatestDefinitionXML(const char* definitionName, StringBuffer& esxdl) = 0;
     virtual IPropertyTree* fetchBinding(const char* espProcess, const char* espStaticBinding) = 0;
     virtual IPropertyTree* fetchBinding(const char* bindingId) = 0;
     virtual bool definitionExists(const char* definitionId) = 0;

+ 179 - 57
esp/services/ws_esdlconfig/ws_esdlconfigservice.cpp

@@ -194,7 +194,7 @@ bool CWsESDLConfigEx::onPublishESDLDefinition(IEspContext &context, IEspPublishE
         Owned<IUserDescriptor> userdesc;
         const char *user = context.queryUserId();
         const char *password = context.queryPassword();
-        if (user && *user && *password && *password)
+        if (user && *user)
         {
             userdesc.setown(createUserDescriptor());
             userdesc->set(user, password, context.querySessionToken(), context.querySignature());
@@ -284,7 +284,11 @@ bool CWsESDLConfigEx::onPublishESDLDefinition(IEspContext &context, IEspPublishE
 
                 try
                 {
-                    m_esdlStore->fetchDefinition(newqueryid.toLowerCase(), definitionxml);
+                    Owned<IPropertyTree> definitionTree;
+                    definitionTree.set(m_esdlStore->fetchDefinition(newqueryid.toLowerCase()));
+                    if(definitionTree)
+                        toXML(definitionTree, definitionxml);
+
                     msg.appendf("\nSuccessfully fetched ESDL Defintion: %s from Dali.", newqueryid.str());
 
                     if (definitionxml.length() == 0 )
@@ -294,44 +298,71 @@ bool CWsESDLConfigEx::onPublishESDLDefinition(IEspContext &context, IEspPublishE
                     }
                     else
                     {
-                        resp.setXMLDefinition(definitionxml.str());
-                        Owned<IPropertyTree> definitionTree = createPTreeFromXMLString(definitionxml.str(), ipt_caseInsensitive);
+                        if (ver >= 1.4)
+                            resp.updateDefinition().setInterface(definitionxml.str());
+                        else
+                            resp.setXMLDefinition(definitionxml.str());
 
                         if (definitionTree)
                         {
                             try
                             {
-                                Owned<IPropertyTreeIterator> iter = definitionTree->getElements("EsdlService/EsdlMethod");
-                                IArrayOf<IEspMethodConfig> list;
-                                ForEach(*iter)
+                                if (ver >= 1.4)
                                 {
-                                    Owned<IEspMethodConfig> methodconfig = createMethodConfig("","");
-                                    IPropertyTree &item = iter->query();
-                                    methodconfig->setName(item.queryProp("@name"));
-                                    list.append(*methodconfig.getClear());
-                                }
-                                resp.setMethods(list);
-                            }
-                            catch (...)
-                            {
-                                msg.append("\nEncountered error while parsing fetching available methods");
-                            }
+                                    IEspPublishHistory& defhistory = resp.updateDefinition().updateHistory();
+                                    addPublishHistory(definitionTree, defhistory);
 
-                            try
-                            {
-                                StringArray esdlServices;
-                                Owned<IPropertyTreeIterator> serviceiter = definitionTree->getElements("EsdlService");
-                                ForEach(*serviceiter)
+                                    IArrayOf<IEspESDLService> respservicesresp;
+                                    Owned<IPropertyTreeIterator> serviceiter = definitionTree->getElements("esxdl/EsdlService");
+                                    ForEach(*serviceiter)
+                                    {
+                                        Owned<IEspESDLService> esdlservice = createESDLService("","");
+                                        IPropertyTree &curservice = serviceiter->query();
+                                        esdlservice->setName(curservice.queryProp("@name"));
+
+                                        Owned<IPropertyTreeIterator> methoditer = curservice.getElements("EsdlMethod");
+                                        IArrayOf<IEspMethodConfig> respmethodsarray;
+                                        ForEach(*methoditer)
+                                        {
+                                            Owned<IEspMethodConfig> methodconfig = createMethodConfig("","");
+                                            IPropertyTree &item = methoditer->query();
+                                            methodconfig->setName(item.queryProp("@name"));
+                                            respmethodsarray.append(*methodconfig.getClear());
+                                        }
+                                        esdlservice->setMethods(respmethodsarray);
+                                        respservicesresp.append(*esdlservice.getClear());
+                                    }
+
+                                    resp.updateDefinition().setServices(respservicesresp);
+                                }
+                                else
                                 {
-                                    IPropertyTree &item = serviceiter->query();
-                                    esdlServices.append(item.queryProp("@name"));
+                                    StringArray esdlServices;
+                                    Owned<IPropertyTreeIterator> serviceiter = definitionTree->getElements("Exsdl/EsdlService");
+                                    ForEach(*serviceiter)
+                                    {
+                                        IPropertyTree &curservice = serviceiter->query();
+                                        esdlServices.append(curservice.queryProp("@name"));
+
+                                        Owned<IPropertyTreeIterator> iter = curservice.getElements("EsdlMethod");
+                                        IArrayOf<IEspMethodConfig> list;
+                                        ForEach(*iter)
+                                        {
+                                            Owned<IEspMethodConfig> methodconfig = createMethodConfig("","");
+                                            IPropertyTree &item = iter->query();
+                                            methodconfig->setName(item.queryProp("@name"));
+                                            list.append(*methodconfig.getClear());
+                                        }
+                                        resp.setMethods(list);
+                                    }
+                                    resp.setESDLServices(esdlServices);
                                 }
-                                resp.setESDLServices(esdlServices);
                             }
                             catch (...)
                             {
-                                msg.append("\nEncountered error while parsing fetching EsdlServices");
+                                msg.append("\nEncountered error while parsing fetching available methods");
                             }
+
                         }
                         else
                             msg.append("\nCould not fetch available methods");
@@ -485,6 +516,9 @@ bool CWsESDLConfigEx::onPublishESDLBinding(IEspContext &context, IEspPublishESDL
                     Owned<IPropertyTree> esdlbindingtree = m_esdlStore->getBindingTree(espProcName.str(), espBindingName.str(), msg);
                     if (esdlbindingtree)
                     {
+                        if ( ver >= 1.4)
+                            addPublishHistory(esdlbindingtree,resp.updateESDLBinding().updateHistory());
+
                         IArrayOf<IEspMethodConfig> iesmethods;
 
                         IPropertyTree * def = esdlbindingtree->queryPropTree("Definition[1]");
@@ -501,7 +535,7 @@ bool CWsESDLConfigEx::onPublishESDLBinding(IEspContext &context, IEspPublishESDL
                             StringBuffer definition;
                             try
                             {
-                                m_esdlStore->fetchDefinition(defid.toLowerCase(), definition);
+                                m_esdlStore->fetchDefinitionXML(defid.toLowerCase(), definition);
                             }
                             catch (...)
                             {
@@ -789,7 +823,10 @@ bool CWsESDLConfigEx::onConfigureESDLBindingMethod(IEspContext &context, IEspCon
                             StringBuffer msg;
                             Owned<IPropertyTree> esdlbindingtree;
                             if (ver >= 1.4)
+                            {
                                 esdlbindingtree.setown(m_esdlStore->getBindingTree(bindingId, msg));
+                                addPublishHistory(esdlbindingtree, resp.updateESDLBinding().updateHistory());
+                            }
                             else
                                 esdlbindingtree.setown(m_esdlStore->getBindingTree(espProcName.str(), espBindingName.str(), msg));
                             if (esdlbindingtree)
@@ -809,7 +846,7 @@ bool CWsESDLConfigEx::onConfigureESDLBindingMethod(IEspContext &context, IEspCon
                                     StringBuffer definition;
                                     try
                                     {
-                                        m_esdlStore->fetchDefinition(defid.toLowerCase(), definition);
+                                        m_esdlStore->fetchDefinitionXML(defid.toLowerCase(), definition);
                                     }
                                     catch (...)
                                     {
@@ -1001,6 +1038,12 @@ bool CWsESDLConfigEx::onGetESDLBinding(IEspContext &context, IEspGetESDLBindingR
                     resp.updateESDLBinding().updateDefinition().setId(defid);
                     resp.updateESDLBinding().updateDefinition().setName(def->queryProp("@name"));
 
+                    if(ver >= 1.4)
+                    {
+                        IEspPublishHistory& defhistory = resp.updateESDLBinding().updateDefinition().updateHistory();
+                        addPublishHistory(def, defhistory);
+                    }
+
                     IArrayOf<IEspMethodConfig> iesmethods;
 
                     if (ver >= 1.2 && req.getReportMethodsAvailable())
@@ -1008,7 +1051,7 @@ bool CWsESDLConfigEx::onGetESDLBinding(IEspContext &context, IEspGetESDLBindingR
                         StringBuffer definition;
                         try
                         {
-                            m_esdlStore->fetchDefinition(defid.toLowerCase(), definition);
+                            m_esdlStore->fetchDefinitionXML(defid.toLowerCase(), definition);
                         }
                         catch (...)
                         {
@@ -1085,7 +1128,7 @@ bool CWsESDLConfigEx::onGetESDLBinding(IEspContext &context, IEspGetESDLBindingR
                         StringBuffer definition;
                         try
                         {
-                            m_esdlStore->fetchDefinition(defid.toLowerCase(), definition);
+                            m_esdlStore->fetchDefinitionXML(defid.toLowerCase(), definition);
                             resp.updateESDLBinding().updateDefinition().setInterface(definition.str());
                             msg.append("\nFetched ESDL Biding definition.");
                         }
@@ -1094,6 +1137,10 @@ bool CWsESDLConfigEx::onGetESDLBinding(IEspContext &context, IEspGetESDLBindingR
                             msg.appendf("\nUnexpected error while attempting to fetch ESDL Definition %s", defid.toLowerCase().str());
                         }
                     }
+
+                    if ( ver >= 1.4)
+                        addPublishHistory(esdlbindingtree,resp.updateESDLBinding().updateHistory());
+
                     resp.updateESDLBinding().updateConfiguration().setMethods(iesmethods);
                     resp.updateStatus().setCode(0);
                 }
@@ -1142,6 +1189,19 @@ bool CWsESDLConfigEx::onGetESDLBinding(IEspContext &context, IEspGetESDLBindingR
     return true;
 }
 
+void CWsESDLConfigEx::addPublishHistory(IPropertyTree * publishedEntryTree, IEspPublishHistory & history)
+{
+    if (publishedEntryTree)
+    {
+         history.setLastEditBy(publishedEntryTree->queryProp("@lastEditedBy"));
+         history.setCreatedTime(publishedEntryTree->queryProp("@created"));
+         history.setPublishBy(publishedEntryTree->queryProp("@publishedBy"));
+         history.setLastEditTime(publishedEntryTree->queryProp("@lastEdit"));
+    }
+    else
+        ESPLOG(LogMin, "Could not fetch ESDL publish history!");
+}
+
 bool CWsESDLConfigEx::onEcho(IEspContext &context, IEspEchoRequest &req, IEspEchoResponse &resp)
 {
     resp.setResponse(req.getRequest());
@@ -1309,6 +1369,7 @@ bool CWsESDLConfigEx::onGetESDLDefinition(IEspContext &context, IEspGetESDLDefin
     StringBuffer message;
     int respcode = 0;
 
+    Owned<IPropertyTree> definitionTree;
     try
     {
         if (ver >= 1.3)
@@ -1323,19 +1384,27 @@ bool CWsESDLConfigEx::onGetESDLDefinition(IEspContext &context, IEspGetESDLDefin
                 }
             }
         }
-        resp.setId(id.str());
-
-        if (strchr (id.str(), '.'))
-            m_esdlStore->fetchDefinition(id.toLowerCase(), definition);
+        if (ver > 1.3)
+            resp.updateDefinition().setId(id.str());
         else
-            m_esdlStore->fetchLatestDefinition(id.toLowerCase(), definition);
+            resp.setId(id.str());
 
-        message.setf("Successfully fetched ESDL Defintion: %s from Dali.", id.str());
-        if (definition.length() == 0 )
+        definitionTree.set(m_esdlStore->fetchDefinition(id.toLowerCase()));
+
+        if (definitionTree)
         {
-            respcode = -1;
-            message.append("\nDefinition appears to be empty!");
+            toXML(definitionTree, definition, 0,0);
+
+            if (definition.length() == 0 )
+            {
+                respcode = -1;
+                message.append("\nDefinition appears to be empty!");
+            }
+            else
+                message.setf("Successfully fetched ESDL Defintion: %s from Dali.", id.str());
         }
+        else
+            throw MakeStringException(-1, "Could not fetch ESDL definition '%s' from Dali.", id.str());
     }
     catch(IException* e)
     {
@@ -1353,23 +1422,55 @@ bool CWsESDLConfigEx::onGetESDLDefinition(IEspContext &context, IEspGetESDLDefin
         throw MakeStringException(-1, "Unexpected error while attempting to fetch ESDL definition.");
     }
 
-    resp.setXMLDefinition(definition.str());
     if (ver >= 1.2)
     {
-        if (definition.length() > 0)
+        if(ver >= 1.4)
+        {
+            resp.updateDefinition().setInterface(definition.str());
+
+            IEspPublishHistory& defhistory = resp.updateDefinition().updateHistory();
+            addPublishHistory(definitionTree, defhistory);
+        }
+        else
+            resp.setXMLDefinition(definition.str());
+
+        if (definition.length() != 0)
         {
-            Owned<IPropertyTree> definitionTree = createPTreeFromXMLString(definition.str(), ipt_caseInsensitive);
             if (req.getReportMethodsAvailable())
             {
-                if (definitionTree)
+                try
                 {
-                    try
+                    VStringBuffer xpath("esxdl/EsdlService");
+                    if (serviceName && *serviceName)
+                        xpath.appendf("[@name='%s']", serviceName);
+
+                    if ( ver >= 1.4)
                     {
-                        StringBuffer xpath;
-                        if (serviceName && *serviceName)
-                            xpath.appendf("EsdlService[@name='%s']/EsdlMethod", serviceName);
-                        else
-                            xpath.set("EsdlService/EsdlMethod");
+                        Owned<IPropertyTreeIterator> services = definitionTree->getElements(xpath.str());
+                        IArrayOf<IEspESDLService> servicesarray;
+                        ForEach(*services)
+                        {
+                            IPropertyTree &curservice = services->query();
+                            Owned<IEspESDLService> esdlservice = createESDLService("","");
+                            esdlservice->setName(curservice.queryProp("@name"));
+
+                            Owned<IPropertyTreeIterator> methods = curservice.getElements("EsdlMethod");
+                            IArrayOf<IEspMethodConfig> methodsarray;
+                            ForEach(*methods)
+                            {
+                                Owned<IEspMethodConfig> methodconfig = createMethodConfig("","");
+                                IPropertyTree &method = methods->query();
+                                methodconfig->setName(method.queryProp("@name"));
+                                methodsarray.append(*methodconfig.getClear());
+                            }
+                            esdlservice->setMethods(methodsarray);
+                            servicesarray.append(*esdlservice.getClear());
+                        }
+                        resp.updateDefinition().setServices(servicesarray);
+                    }
+                    else
+                    {
+                        xpath.append("/EsdlMethod");
                         Owned<IPropertyTreeIterator> iter = definitionTree->getElements(xpath.str());
                         IArrayOf<IEspMethodConfig> list;
                         ForEach(*iter)
@@ -1381,13 +1482,11 @@ bool CWsESDLConfigEx::onGetESDLDefinition(IEspContext &context, IEspGetESDLDefin
                         }
                         resp.setMethods(list);
                     }
-                    catch (...)
-                    {
-                        message.append("\nEncountered error while parsing fetching available methods");
-                    }
                 }
-                else
-                    message.append("\nCould not fetch available methods");
+                catch (...)
+                {
+                    message.append("\nEncountered error while parsing fetching available methods");
+                }
             }
 
             if (definitionTree)
@@ -1434,6 +1533,9 @@ bool CWsESDLConfigEx::onListESDLDefinitions(IEspContext &context, IEspListESDLDe
     Owned<IPropertyTree> esdlDefinitions = m_esdlStore->getDefinitions();
     if(esdlDefinitions.get() == nullptr)
         return false;
+
+    double ver = context.getClientVersion();
+
     Owned<IPropertyTreeIterator> iter = esdlDefinitions->getElements("Definition");
     IArrayOf<IEspESDLDefinition> list;
     ForEach(*iter)
@@ -1443,7 +1545,15 @@ bool CWsESDLConfigEx::onListESDLDefinitions(IEspContext &context, IEspListESDLDe
         esdldefinition->setId(item.queryProp("@id"));
         esdldefinition->setName(item.queryProp("@name"));
         esdldefinition->setSeq(item.getPropInt("@seq"));
+
+        if(ver >= 1.4)
+        {
+            IEspPublishHistory& defhistory = esdldefinition->updateHistory();
+            addPublishHistory(&item, defhistory);
+        }
+
         list.append(*esdldefinition.getClear());
+
     }
     resp.setDefinitions(list);
 
@@ -1455,6 +1565,8 @@ bool CWsESDLConfigEx::onListDESDLEspBindings(IEspContext &context, IEspListDESDL
     if (m_isDetachedFromDali)
         throw MakeStringException(-1, "Cannot list ESDL ESP Bindings. ESP is currently detached from DALI.");
 
+    double ver = context.getClientVersion();
+
     bool includeESDLBindings = req.getIncludeESDLBindingInfo();
     IArrayOf<IEspESPServerEx> allESPServers;
     IArrayOf<IEspESPServerEx> desdlESPServers;
@@ -1500,6 +1612,9 @@ bool CWsESDLConfigEx::onListDESDLEspBindings(IEspContext &context, IEspListDESDL
                         desdlespbinding->updateESDLBinding().updateDefinition().setId(defid);
                         desdlespbinding->updateESDLBinding().updateDefinition().setName(def->queryProp("@name"));
 
+                        if (ver >= 1.4)
+                            addPublishHistory(esdlbindingtree,desdlespbinding->updateESDLBinding().updateHistory());
+
                         IArrayOf<IEspMethodConfig> iesmethods;
                         Owned<IPropertyTreeIterator> iter = esdlbindingtree->getElements("Definition[1]/Methods/Method");
                         ForEach(*iter)
@@ -1533,7 +1648,7 @@ bool CWsESDLConfigEx::onListDESDLEspBindings(IEspContext &context, IEspListDESDL
                         StringBuffer definition;
                         try
                         {
-                            m_esdlStore->fetchDefinition(defid.toLowerCase(), definition);
+                            m_esdlStore->fetchDefinitionXML(defid.toLowerCase(), definition);
                             if (definition.length() != 0)
                             {
                                 desdlespbinding->updateESDLBinding().updateDefinition().setInterface(definition.str());
@@ -1642,10 +1757,17 @@ bool CWsESDLConfigEx::onListESDLBindings(IEspContext &context, IEspListESDLBindi
             else
                 esdlbinding->setPort(0);
             esdlbinding->setEspBinding(item.queryProp("@espbinding"));
+
+            if( ver >= 1.4)
+            {
+                IEspPublishHistory& bindhistory = esdlbinding->updateHistory();
+                addPublishHistory(&item, bindhistory);
+            }
             list.append(*esdlbinding.getClear());
         }
         list.sort(bindingCompareFunc);
     }
+
     if (ver >= 1.4)
     {
         StringArray allProcNamesSorted;

+ 3 - 0
esp/services/ws_esdlconfig/ws_esdlconfigservice.hpp

@@ -55,6 +55,9 @@ public:
     bool onListESDLBindings(IEspContext &context, IEspListESDLBindingsRequest&req, IEspListESDLBindingsResponse &resp);
     bool onListDESDLEspBindings(IEspContext &context, IEspListDESDLEspBindingsReq&req, IEspListDESDLEspBindingsResp &resp);
 
+    bool addESDLBindingContentsHistory(IPropertyTree * publishedEntryTree, IEspESDLBindingContents& esdlbindingcontents);
+    void addPublishHistory(IPropertyTree * publishedEntryTree, IEspPublishHistory &resp);
+
     bool attachServiceToDali() override
     {
         m_isDetachedFromDali = false;

+ 7 - 1
tools/esdlcmd/esdl-publish.cpp

@@ -1177,7 +1177,13 @@ class EsdlGetDefinitionCmd : public EsdlGetCmd
                 return 1;
             }
 
-            fprintf(stdout, "\n%s", resp->getXMLDefinition());
+            StringBuffer definition;
+            definition.set(resp->getXMLDefinition());
+
+            if (definition.length()==0) //as of wsesdlconfig 1.4 getxmldef moves to definition/Interface
+                definition.set(resp->getDefinition().getInterface());
+
+            fprintf(stdout, "\n%s", definition.str());
             fprintf(stdout, "\n%s.\n", resp->getStatus().getDescription());
 
             return 0;