Bläddra i källkod

Merge pull request #4926 from wangkx/h9772

HPCC-10156 Add TpListTargetClusters method to WsTopology

Reviewed-By: Gordon Smith <gordon.smith@lexisnexis.com>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 11 år sedan
förälder
incheckning
5d68421995

+ 17 - 0
esp/scm/ws_topology.ecm

@@ -262,6 +262,22 @@ ESPStruct TpServices
     ESParray<ESPstruct TpSashaServer> TpSashaServers;
 };
 
+ESPStruct TpClusterNameType
+{
+    string Name;
+    string Type;
+    bool   IsDefault;
+};
+
+ESPrequest TpListTargetClustersRequest
+{
+};
+
+ESPresponse [exceptions_inline] TpListTargetClustersResponse
+{
+    ESParray<ESPstruct TpClusterNameType>   TargetClusters;
+};
+
 //  ===========================================================================
 ESPStruct TpTargetCluster
 {
@@ -583,6 +599,7 @@ ESPservice [noforms, version("1.19"), default_client_version("1.19"), exceptions
     ESPmethod [resp_xsl_default("/esp/xslt/tplog.xslt")] TpLogFile(TpLogFileRequest, TpLogFileResponse);
     ESPmethod [resp_xsl_default("/esp/xslt/tplogdisplay.xslt")] TpLogFileDisplay(TpLogFileRequest, TpLogFileResponse);
     ESPmethod TpGetComponentFile(TpGetComponentFileRequest, TpGetComponentFileResponse);
+    ESPmethod TpListTargetClusters(TpListTargetClustersRequest, TpListTargetClustersResponse);
 
     ESPmethod SystemLog(SystemLogRequest, SystemLogResponse);
 };

+ 103 - 0
esp/services/ws_topology/ws_topologyService.cpp

@@ -74,6 +74,15 @@ void CWsTopologyEx::init(IPropertyTree *cfg, const char *process, const char *se
     xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/PreflightProcessFilter", process, service);
     cfg->getProp(xpath.str(), m_preflightProcessFilter);
 
+    xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/DefaultTargetCluster/@name", process, service);
+    if (cfg->hasProp(xpath.str()))
+    {
+        defaultTargetClusterName.set(cfg->queryProp(xpath.str()));
+        xpath.clear().appendf("Software/EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]/DefaultTargetCluster/@prefix", process, service);
+        if (cfg->hasProp(xpath.str()))
+            defaultTargetClusterPrefix.set(cfg->queryProp(xpath.str()));
+    }
+
     m_enableSNMP = false;
 }
 
@@ -952,6 +961,100 @@ bool CWsTopologyEx::onTpClusterQuery(IEspContext &context, IEspTpClusterQueryReq
     return false;
 }
 
+bool CWsTopologyEx::onTpListTargetClusters(IEspContext &context, IEspTpListTargetClustersRequest &req, IEspTpListTargetClustersResponse &resp)
+{
+    try
+    {
+        if (!context.validateFeatureAccess(FEATURE_URL, SecAccess_Read, false))
+            throw MakeStringException(ECLWATCH_TOPOLOGY_ACCESS_DENIED, "Failed to do Cluster Query. Permission denied.");
+
+        //another client (like configenv) may have updated the constant environment so reload it
+        m_envFactory->validateCache();
+
+        Owned<IRemoteConnection> conn = querySDS().connect("Environment", myProcessSession(), RTM_LOCK_READ, SDS_LOCK_TIMEOUT);
+        if (!conn)
+            return false;
+
+        bool foundDefault = false;
+        bool hasHThor = false;
+        bool hasThor = false;
+        const char* defaultClusterName = defaultTargetClusterName.get();
+        const char* defaultClusterPrefix = defaultTargetClusterPrefix.get();
+        IArrayOf<IEspTpClusterNameType> clusters;
+        Owned<IPropertyTreeIterator> targets = conn->queryRoot()->getElements("Software/Topology/Cluster");
+        ForEach(*targets)
+        {
+            IPropertyTree &target = targets->query();
+            const char* name = target.queryProp("@name");
+            const char* prefix = target.queryProp("@prefix");
+            if (!name || !*name || !prefix || !*prefix)
+                continue;//invalid entry
+
+            Owned<IEspTpClusterNameType> tc = new CTpClusterNameType("", "");
+            tc->setName(name);
+            tc->setType(prefix);
+
+            if (defaultClusterName && defaultClusterPrefix && strieq(defaultClusterName, name) &&
+                strieq(defaultClusterPrefix, prefix))
+            {
+                foundDefault = true;
+                tc->setIsDefault(true);
+            }
+
+            if (!foundDefault && !hasHThor)
+            {
+                ClusterType targetClusterType = HThorCluster;
+                getClusterType(prefix, targetClusterType);
+                if (targetClusterType == HThorCluster)
+                        hasHThor = true;
+                else if (targetClusterType == ThorLCRCluster)
+                        hasThor = true;
+            }
+
+            clusters.append(*tc.getLink());
+        }
+        if (!foundDefault)
+        {  //No default target is specified or the default target does not match with any. Use the
+            //following rules to decide a default target: if an hthor is found, it will be the 'default';
+            //if no hthor, the first thor cluster will be the 'default';
+            //If no hthor and no thor, the first roxie cluster will be the 'default'.
+            ForEachItemIn(i, clusters)
+            {
+                IEspTpClusterNameType& tc = clusters.item(i);
+                if (hasHThor)
+                {
+                    ClusterType targetClusterType = HThorCluster;
+                    if (HThorCluster == getClusterType(tc.getType(), targetClusterType))
+                    {
+                        tc.setIsDefault(true);
+                        break;
+                    }
+                }
+                else if (hasThor)
+                {
+                    ClusterType targetClusterType = HThorCluster;
+                    if (ThorLCRCluster == getClusterType(tc.getType(), targetClusterType))
+                    {
+                        tc.setIsDefault(true);
+                        break;
+                    }
+                }
+                else
+                {
+                    tc.setIsDefault(true);
+                    break;
+                }
+            }
+        }
+        resp.setTargetClusters(clusters);
+    }
+    catch(IException* e)
+    {
+        FORWARDEXCEPTION(context, e,  ECLWATCH_INTERNAL_ERROR);
+    }
+    return false;
+}
+
 bool CWsTopologyEx::onTpTargetClusterQuery(IEspContext &context, IEspTpTargetClusterQueryRequest &req, IEspTpTargetClusterQueryResponse &resp)
 {
     try

+ 4 - 0
esp/services/ws_topology/ws_topologyService.hpp

@@ -87,6 +87,8 @@ private:
     bool                                m_bDiskThresholdIsPercentage;
     bool                                m_bEncapsulatedSystem;
     bool                                m_enableSNMP;
+    StringAttr                          defaultTargetClusterName;
+    StringAttr                          defaultTargetClusterPrefix;
 
     void getThorXml(const char *cluster,StringBuffer& strBuff);
     void getThorLog(const char *cluster,MemoryBuffer& returnbuff);
@@ -117,6 +119,8 @@ public:
 
     bool onTpClusterQuery(IEspContext &context, IEspTpClusterQueryRequest &req, IEspTpClusterQueryResponse &resp);
 
+    bool onTpListTargetClusters(IEspContext &context, IEspTpListTargetClustersRequest &req, IEspTpListTargetClustersResponse &resp);
+
     bool onTpTargetClusterQuery(IEspContext &context, IEspTpTargetClusterQueryRequest &req, IEspTpTargetClusterQueryResponse &resp);
 
     bool onTpLogicalClusterQuery(IEspContext &context, IEspTpLogicalClusterQueryRequest &req, IEspTpLogicalClusterQueryResponse &resp);