Browse Source

HPCC-23473 Update roxie to support new config paradigm

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 5 years ago
parent
commit
01530e2545
1 changed files with 96 additions and 101 deletions
  1. 96 101
      roxie/ccd/ccdmain.cpp

+ 96 - 101
roxie/ccd/ccdmain.cpp

@@ -126,6 +126,7 @@ bool preloadOnceData;
 bool reloadRetriesFailed;
 bool selfTestMode = false;
 bool defaultCollectFactoryStatistics = true;
+bool useOldTopology = false;
 
 int backgroundCopyClass = 0;
 int backgroundCopyPrio = 0;
@@ -337,12 +338,11 @@ static void roxie_common_usage(const char * progName)
     // Things that are also relevant to stand-alone executables
     printf("Usage: %s [options]\n", program.str());
     printf("\nOptions:\n");
-    printf("  -[xml|csv|raw]            : Output format (default ascii)\n");
+    printf("  --[xml|csv|raw]           : Output format (default ascii)\n");
     printf("  --daliServers=[host1,...] : List of Dali servers to use\n");
     printf("  --tracelevel=[integer]    : Amount of information to dump on logs\n");
     printf("  --stdlog=[boolean]        : Standard log format (based on tracelevel)\n");
     printf("  --logfile=[filename]      : Outputs to logfile, rather than stdout\n");
-    printf("  --topology=[filename]     : Load configuration from named xml file (default RoxieTopology.xml)\n");
     printf("  --help|-h                 : This message\n");
     printf("\n");
 }
@@ -377,6 +377,8 @@ void saveTopology()
     // Write back changes that have been made via certain control:xxx changes, so that they survive a roxie restart
     // Note that they are overwritten when Roxie is manually stopped/started via hpcc-init service - these changes
     // are only intended to be temporary for the current session
+    if (!useOldTopology)
+        return;
     try
     {
         saveXML(topologyFile.str(), topology);
@@ -412,20 +414,6 @@ static std::vector<RoxieEndpointInfo> myRoles;
 static std::vector<unsigned> farmerPorts;
 static std::vector<std::pair<unsigned, unsigned>> slaveChannels;
 
-static bool splitarg(const char *arg, std::string &name, std::string &value)
-{
-    const char *eq = strchr(arg, '=');
-    if (eq)
-    {
-        name.append(arg, eq-arg);
-        value.append(eq+1);
-        return true;
-    }
-    else
-        return false;
-}
-
-
 void readStaticTopology()
 {
     // If dynamicServers not set, we read a list of all servers form the topology file, and deduce which ones are on which channel
@@ -537,6 +525,29 @@ void readStaticTopology()
     createStaticTopology(allRoles, traceLevel);
 }
 
+static constexpr const char * defaultJson = R"!!({
+  "version": "1.0",
+  "Roxie": {
+    "allFilesDynamic": true,
+    "numChannels": 1,
+    "localSlave": true,
+    "resolveLocally": true,
+    "numServerThreads": 30,
+    "serverPorts": "9876,0",
+    "RoxieFarmProcess":  {
+      "name": "default",
+      "port": 9876,
+      "listenQueue": 200,
+      "numThreads": 0
+    },
+    "RoxieFarmProcess":  {
+      "name": "workunit",
+      "port": 0,
+      "numThreads": 0
+    },
+  },
+})!!";
+
 int STARTQUERY_API start_query(int argc, const char *argv[])
 {
     for (unsigned i=0;i<(unsigned)argc;i++) {
@@ -564,7 +575,6 @@ int STARTQUERY_API start_query(int argc, const char *argv[])
     }
     init_signals();
 
-    // stand alone usage only, not server
     for (unsigned i=0; i<(unsigned)argc; i++)
     {
         if (stricmp(argv[i], "--help")==0 ||
@@ -573,10 +583,16 @@ int STARTQUERY_API start_query(int argc, const char *argv[])
             roxie_common_usage(argv[0]);
             return EXIT_SUCCESS;
         }
+        else if (strsame(argv[i], "-xml"))  // Back compatibility
+            argv[i] = "--xml";
+        else if (strsame(argv[i], "-csv"))
+            argv[i] = "--csv";
+        else if (strsame(argv[i], "-raw"))
+            argv[i] = "--raw";
     }
 
     #ifdef _USE_CPPUNIT
-    if (argc>=2 && stricmp(argv[1], "-selftest")==0)
+    if (argc>=2 && (stricmp(argv[1], "-selftest")==0 || stricmp(argv[1], "--selftest")==0))
     {
         selfTestMode = true;
         queryStderrLogMsgHandler()->setMessageFields(MSGFIELD_time | MSGFIELD_milliTime | MSGFIELD_prefix);
@@ -629,83 +645,54 @@ int STARTQUERY_API start_query(int argc, const char *argv[])
     addNonEmptyPathSepChar(codeDirectory);
     try
     {
-        Owned<IProperties> globals = createProperties(true);
-        for (int i = 1; i < argc; i++)
+        Owned<IFile> sentinelFile = createSentinelTarget();
+        removeSentinelFile(sentinelFile);
+
+        topologyFile.append(codeDirectory).append(PATHSEPCHAR).append("RoxieTopology.xml");
+        useOldTopology = checkFileExists(topologyFile.str());
+        topology = loadConfiguration(useOldTopology ? nullptr : defaultJson, argv, "Roxie", "ROXIE", topologyFile, nullptr);
+        saveTopology();
+        const char *channels = topology->queryProp("@channels");
+        if (channels)
         {
-            std::string name, value;
-            if (splitarg(argv[i], name, value))
+            StringArray channelSpecs;
+            channelSpecs.appendList(channels, ",", true);
+            ForEachItemIn(idx, channelSpecs)
             {
-                if (name=="--topologyServer")
-                {
-                    topologyServers.append(SocketEndpoint(value.c_str()));
-                    continue;
-                }
-                else if (name=="--serverPort")
+                char *tail = nullptr;
+                unsigned channel = strtoul(channelSpecs.item(idx), &tail, 10);
+                unsigned repl = 0;
+                if (*tail==':')
                 {
-                    farmerPorts.push_back(atoi(value.c_str()));
-                    continue;
-                }
-                else if (name=="--channel")
-                {
-                    char *tail = nullptr;
-                    unsigned channel = strtoul(value.c_str(), &tail, 10);
-                    unsigned repl = 0;
-                    if (*tail==':')
-                    {
-                        tail++;
-                        repl = atoi(tail);
-                    }
-                    slaveChannels.push_back(std::pair<unsigned, unsigned>(channel, repl));
-                    continue;
+                    tail++;
+                    repl = atoi(tail);
                 }
+                else if (*tail)
+                    throw makeStringExceptionV(ROXIE_INTERNAL_ERROR, "Invalid channel specification %s", channels);
+                slaveChannels.push_back(std::pair<unsigned, unsigned>(channel, repl));
             }
-            globals->loadProp(argv[i], true);
         }
-        Owned<IFile> sentinelFile = createSentinelTarget();
-        removeSentinelFile(sentinelFile);
-
-        if (globals->hasProp("--topology"))
-            globals->getProp("--topology", topologyFile);
-        else
-            topologyFile.append(codeDirectory).append(PATHSEPCHAR).append("RoxieTopology.xml");
-
-        if (checkFileExists(topologyFile.str()))
+        const char *topos = topology->queryProp("@topologyServers");
+        if (topos)
         {
-            DBGLOG("Loading topology file %s", topologyFile.str());
-            topology = createPTreeFromXMLFile(topologyFile.str(), ipt_lowmem);
-            saveTopology();
-            if (globals->hasProp("--udpTraceLevel"))
-                topology->setProp("@udpTraceLevel", globals->queryProp("--udpTraceLevel"));
-            if (globals->hasProp("--traceLevel"))
-                topology->setProp("@traceLevel", globals->queryProp("--traceLevel"));
-            if (globals->hasProp("--prestartSlaveThreads"))
-                topology->setProp("@prestartSlaveThreads", globals->queryProp("--prestartSlaveThreads"));
+            StringArray topoValues;
+            topoValues.appendList(topos, ",", true);
+            ForEachItemIn(idx, topoValues)
+            {
+                topologyServers.append(SocketEndpoint(topoValues.item(idx)));  // MORE - in cloud case we may need to explicitly find all pods for a single service?
+            }
         }
-        else
+        const char *serverPorts = topology->queryProp("@serverPorts");
+        if (serverPorts)
         {
-            if (globals->hasProp("--topology"))
+            StringArray values;
+            values.appendList(serverPorts, ",", true);
+            ForEachItemIn(idx, values)
             {
-                // Explicitly-named topology file SHOULD exist...
-                throw MakeStringException(ROXIE_INVALID_TOPOLOGY, "topology file %s not found", topologyFile.str());
+                farmerPorts.push_back(atoi(values.item(idx)));
             }
-            topology=createPTreeFromXMLString(
-                "<RoxieTopology allFilesDynamic='1' localSlave='1' resolveLocally='1'>"
-                " <RoxieFarmProcess/>"
-                " <RoxieServerProcess netAddress='.'/>"
-                "</RoxieTopology>"
-                , ipt_lowmem
-                );
-            int port = globals->getPropInt("--port", 9876);
-            topology->setPropInt("RoxieFarmProcess/@port", port);
-            topology->setProp("@daliServers", globals->queryProp("--daliServers"));
-            topology->setProp("@traceLevel", globals->queryProp("--traceLevel"));
-            topology->setPropBool("@traceStartStop", globals->getPropInt("--traceStartStop", 0));
-            topology->setPropInt("@allFilesDynamic", globals->getPropInt("--allFilesDynamic", 1));
-            topology->setProp("@memTraceLevel", globals->queryProp("--memTraceLevel"));
-            topology->setPropInt64("@totalMemoryLimit", globals->getPropInt("--totalMemoryLimitMb", 0) * (memsize_t) 0x100000);
-            topology->setProp("@disableLocalOptimizations", globals->queryProp("--disableLocalOptimizations"));
-            topology->setPropInt("@indexReadChunkSize", globals->getPropInt("--indexReadChunkSize", 60000));
         }
+
         if (topology->hasProp("PreferredCluster"))
         {
             preferredClusters = new MapStringTo<int>(true);
@@ -726,20 +713,26 @@ int STARTQUERY_API start_query(int argc, const char *argv[])
             setStatisticsComponentName(SCTroxie, "roxie", true);
 
         Owned<const IQueryDll> standAloneDll;
-        if (globals->hasProp("--loadWorkunit"))
+        if (topology->hasProp("@loadWorkunit"))
         {
             StringBuffer workunitName;
-            globals->getProp("--loadWorkunit", workunitName);
+            topology->getProp("@loadWorkunit", workunitName);
             standAloneDll.setown(createQueryDll(workunitName));
-            runOnce = globals->getPropInt("--port", 0) == 0;
         }
         else
         {
             Owned<ILoadedDllEntry> dll = createExeDllEntry(argv[0]);
             if (checkEmbeddedWorkUnitXML(dll))
-            {
                 standAloneDll.setown(createExeQueryDll(argv[0]));
-                runOnce = globals->getPropInt("--port", 0) == 0;
+        }
+        if (standAloneDll)
+        {
+            unsigned port = topology->getPropInt("@port", 0);
+            runOnce = port == 0;
+            if (port)
+            {
+                farmerPorts.clear();
+                farmerPorts.push_back(port);
             }
         }
 
@@ -774,11 +767,11 @@ int STARTQUERY_API start_query(int argc, const char *argv[])
         directoryTree.clear();
 
         //Logging stuff
-        if (globals->getPropBool("--stdlog", traceLevel != 0) || topology->getPropBool("@forceStdLog", false))
+        if (topology->getPropBool("@stdlog", traceLevel != 0) || topology->getPropBool("@forceStdLog", false))
             queryStderrLogMsgHandler()->setMessageFields(MSGFIELD_time | MSGFIELD_milliTime | MSGFIELD_thread | MSGFIELD_prefix);
         else
             removeLog();
-        if (globals->hasProp("--logfile"))
+        if (topology->hasProp("@logfile"))
         {
             Owned<IComponentLogFileCreator> lf = createComponentLogFileCreator(topology, "roxie");
             lf->setMaxDetail(TopDetail);
@@ -796,7 +789,7 @@ int STARTQUERY_API start_query(int argc, const char *argv[])
                 queryLogMsgManager()->enterQueueingMode();
                 queryLogMsgManager()->setQueueDroppingLimit(logQueueLen, logQueueDrop);
             }
-            if (globals->getPropBool("--enableSysLog",true))
+            if (topology->getPropBool("@enableSysLog",true))
                 UseSysLogForOperatorMessages();
         }
 
@@ -814,7 +807,7 @@ int STARTQUERY_API start_query(int argc, const char *argv[])
                 throw MakeStringException(ROXIE_INTERNAL_ERROR, "Invalid UserMetric element in topology file - name or regex missing");
         }
 
-        restarts = globals->getPropInt("--restarts", 0);
+        restarts = topology->getPropInt("@restarts", 0);
         const char *preferredSubnet = topology->queryProp("@preferredSubnet");
         if (preferredSubnet)
         {
@@ -862,7 +855,7 @@ int STARTQUERY_API start_query(int argc, const char *argv[])
             Owned<IPropertyTree> nas = envGetNASConfiguration(topology);
             envInstallNASHooks(nas);
         }
-        useDynamicServers = topology->getPropBool("@useDynamicServers", topologyServers.length()>0);
+        useDynamicServers = topology->getPropBool("@useDynamicServers", !useOldTopology);
         useAeron = topology->getPropBool("@useAeron", useDynamicServers);
         localSlave = topology->getPropBool("@localSlave", false);
         numChannels = topology->getPropInt("@numChannels", 0);
@@ -1135,9 +1128,9 @@ int STARTQUERY_API start_query(int argc, const char *argv[])
             IpAddress myIP(".");
             for (unsigned port: farmerPorts)
             {
-                VStringBuffer xpath("./RoxieFarmProcess[@port='%u']", port);
+                VStringBuffer xpath("RoxieFarmProcess[@port='%u']", port);
                 if (!topology->hasProp(xpath))
-                    topology->addPropTree("./RoxieFarmProcess")->setPropInt("@port", port);
+                    topology->addPropTree("RoxieFarmProcess")->setPropInt("@port", port);
                 RoxieEndpointInfo me = {RoxieEndpointInfo::RoxieServer, 0, { (unsigned short) port, myIP }, 0};
                 myRoles.push_back(me);
             }
@@ -1185,7 +1178,7 @@ int STARTQUERY_API start_query(int argc, const char *argv[])
         Owned<IHpccProtocolPluginContext> protocolCtx = new CHpccProtocolPluginCtx();
         if (runOnce)
         {
-            if (globals->hasProp("--wu"))
+            if (topology->getPropBool("@wu", false))
             {
                 Owned<IHpccProtocolListener> roxieServer = createRoxieWorkUnitListener(1, false);
                 try
@@ -1206,14 +1199,14 @@ int STARTQUERY_API start_query(int argc, const char *argv[])
                 Owned<IHpccProtocolListener> roxieServer = protocolPlugin->createListener("runOnce", createRoxieProtocolMsgSink(myNode.getNodeAddress(), 0, 1, false), 0, 0, NULL);
                 try
                 {
-                    const char *format = globals->queryProp("-format");
+                    const char *format = topology->queryProp("@format");
                     if (!format)
                     {
-                        if (globals->hasProp("--xml") || globals->hasProp("-xml"))  // Support - versions for compatibility
+                        if (topology->getPropBool("@xml", false))
                             format = "xml";
-                        else if (globals->hasProp("--csv") || globals->hasProp("-csv"))
+                        else if (topology->getPropBool("@csv", false))
                             format = "csv";
-                        else if (globals->hasProp("-raw") || globals->hasProp("--raw"))
+                        else if (topology->getPropBool("@raw", false))
                             format = "raw";
                         else
                             format = "ascii";
@@ -1239,7 +1232,9 @@ int STARTQUERY_API start_query(int argc, const char *argv[])
                 {
                     IPropertyTree &roxieFarm = roxieFarms->query();
                     unsigned listenQueue = roxieFarm.getPropInt("@listenQueue", DEFAULT_LISTEN_QUEUE_SIZE);
-                    unsigned numThreads = roxieFarm.getPropInt("@numThreads", numServerThreads);
+                    unsigned numThreads = roxieFarm.getPropInt("@numThreads", 0);
+                    if (!numThreads)
+                        numThreads = numServerThreads;
                     unsigned port = roxieFarm.getPropInt("@port", ROXIE_SERVER_PORT);
                     if (useDynamicServers)
                     {