Explorar el Código

HPCC-24598 Improve helm service definitions and add to configMaps

1. Rename default eclagent roxie to "roxie-workunit".
2. Remove queue for roxie-cluster.  Users can use "roxie-workunit"
3. Rename default roxie cluster to "roxie".
4. Rename default roxie service to "roxie".
5. Make service name match roxie.services name exactly rather than
   mangling the names.  User can be explicit.
6. Fix WsEcl cluster resolution using generated config maps.
7. Fix WsEcl::jsontest to not use relative file paths for included
   resources.

Signed-off-by: Anthony Fishbeck <anthony.fishbeck@lexisnexisrisk.com>
Richard Chapman hace 4 años
padre
commit
06d06d4538

+ 100 - 47
esp/services/ws_ecl/ws_ecl_service.cpp

@@ -196,57 +196,36 @@ static void appendServerAddress(StringBuffer &s, IPropertyTree &env, IPropertyTr
     s.append(netAddress).append(':').append(port ? port : "9876");
 }
 
-bool CWsEclService::init(const char * name, const char * type, IPropertyTree * cfg, const char * process)
+void initContainerRoxieTargets(MapStringToMyClass<ISmartSocketFactory> &connMap)
 {
-    StringBuffer xpath;
-    xpath.appendf("Software/EspProcess[@name='%s']", process);
-    IPropertyTree *prc = cfg->queryPropTree(xpath.str());
-    if (!prc)
-        throw MakeStringException(-1, "ESP Process %s not configured", process);
+    Owned<IPropertyTreeIterator> services = queryComponentConfig().getElements("services[@type='roxie']");
+    ForEach(*services)
+    {
+        IPropertyTree &service = services->query();
+        const char *name = service.queryProp("@name");
+        const char *target = service.queryProp("@target");
+        const char *port = service.queryProp("@port");
 
-    auth_method.set(prc->queryProp("Authentication/@method"));
-    portal_URL.set(prc->queryProp("@portalurl"));
+        if (isEmptyString(target) || isEmptyString(name)) //bad config?
+            continue;
 
-    StringBuffer daliAddress;
-    const char *daliServers = prc->queryProp("@daliServers");
-    if (daliServers)
-    {
-        while (*daliServers && !strchr(":;,", *daliServers))
-            daliAddress.append(*daliServers++);
+        StringBuffer s;
+        s.append(name).append(':').append(port ? port : "9876");
+        Owned<ISmartSocketFactory> sf = new RoxieSocketFactory(s.str(), false, true, nullptr, (unsigned) -1);
+        connMap.setValue(target, sf.get());
     }
+}
+
+void initBareMetalRoxieTargets(MapStringToMyClass<ISmartSocketFactory> &connMap, IPropertyTree *serviceTree, const char *daliAddress)
+{
+    IPropertyTree *vips = serviceTree->queryPropTree("VIPS");
+    Owned<IStringIterator> roxieTargets = getTargetClusters("RoxieCluster", NULL);
 
     Owned<IEnvironmentFactory> factory = getEnvironmentFactory(true);
     Owned<IConstEnvironment> environment = factory->openEnvironment();
     Owned<IPropertyTree> pRoot = &environment->getPTree();
 
-    xpath.clear().appendf("EspService[@name='%s']", name);
-    IPropertyTree *serviceTree = prc->queryPropTree(xpath);
-    if (!serviceTree)
-        throw MakeStringException(-1, "ESP Service %s not configured", name);
-
-    roxieTimeout = serviceTree->getPropInt("RoxieTimeout", 10 * 60);
-    if (!roxieTimeout)
-        roxieTimeout = WAIT_FOREVER;
-    workunitTimeout = serviceTree->getPropInt("WorkunitTimeout", 10 * 60);
-    if (workunitTimeout)
-        workunitTimeout *= 1000;
-    else
-        workunitTimeout = WAIT_FOREVER;
-
-    const char *headerName = serviceTree->queryProp("HttpGlobalIdHeader");
-    if (headerName && *headerName && !streq(headerName, "Global-Id") && !streq(headerName, "HPCC-Global-Id")) //defaults will be checked anyway
-        globalIdHttpHeader.set(headerName);
-    headerName = serviceTree->queryProp("HttpCallerIdHeader");
-    if (headerName && *headerName && !streq(headerName, "Caller-Id") && !streq(headerName, "HPCC-Caller-Id")) //defaults will be checked anyway
-        callerIdHttpHeader.set(headerName);
-
-    Owned<IPropertyTreeIterator> cfgTargets = serviceTree->getElements("Targets/Target");
-    ForEach(*cfgTargets)
-        targets.append(cfgTargets->query().queryProp(NULL));
-
-    IPropertyTree *vips = serviceTree->queryPropTree("VIPS");
-    Owned<IStringIterator> roxieTargets = getTargetClusters("RoxieCluster", NULL);
-
+    StringBuffer xpath;
     ForEach(*roxieTargets)
     {
         SCMStringBuffer target;
@@ -289,7 +268,7 @@ bool CWsEclService::init(const char * name, const char * type, IPropertyTree * c
             {
                 Owned<IPropertyTreeIterator> servers = it->query().getElements("RoxieServerProcess");
                 ForEach(*servers)
-                    appendServerAddress(list, *pRoot, servers->query(), daliAddress.str());
+                    appendServerAddress(list, *pRoot, servers->query(), daliAddress);
             }
         }
         if (list.length())
@@ -301,7 +280,56 @@ bool CWsEclService::init(const char * name, const char * type, IPropertyTree * c
                 connMap.setValue(alias.str(), sf.get());
         }
     }
+}
+bool CWsEclService::init(const char * name, const char * type, IPropertyTree * cfg, const char * process)
+{
+    StringBuffer xpath;
+    xpath.appendf("Software/EspProcess[@name='%s']", process);
+    IPropertyTree *prc = cfg->queryPropTree(xpath.str());
+    if (!prc)
+        throw MakeStringException(-1, "ESP Process %s not configured", process);
+
+    auth_method.set(prc->queryProp("Authentication/@method"));
+    portal_URL.set(prc->queryProp("@portalurl"));
 
+    StringBuffer daliAddress;
+    const char *daliServers = prc->queryProp("@daliServers");
+    if (daliServers)
+    {
+        while (*daliServers && !strchr(":;,", *daliServers))
+            daliAddress.append(*daliServers++);
+    }
+
+    xpath.clear().appendf("EspService[@name='%s']", name);
+    IPropertyTree *serviceTree = prc->queryPropTree(xpath);
+    if (!serviceTree)
+        throw MakeStringException(-1, "ESP Service %s not configured", name);
+
+    roxieTimeout = serviceTree->getPropInt("RoxieTimeout", 10 * 60);
+    if (!roxieTimeout)
+        roxieTimeout = WAIT_FOREVER;
+    workunitTimeout = serviceTree->getPropInt("WorkunitTimeout", 10 * 60);
+    if (workunitTimeout)
+        workunitTimeout *= 1000;
+    else
+        workunitTimeout = WAIT_FOREVER;
+
+    const char *headerName = serviceTree->queryProp("HttpGlobalIdHeader");
+    if (headerName && *headerName && !streq(headerName, "Global-Id") && !streq(headerName, "HPCC-Global-Id")) //defaults will be checked anyway
+        globalIdHttpHeader.set(headerName);
+    headerName = serviceTree->queryProp("HttpCallerIdHeader");
+    if (headerName && *headerName && !streq(headerName, "Caller-Id") && !streq(headerName, "HPCC-Caller-Id")) //defaults will be checked anyway
+        callerIdHttpHeader.set(headerName);
+
+    Owned<IPropertyTreeIterator> cfgTargets = serviceTree->getElements("Targets/Target");
+    ForEach(*cfgTargets)
+        targets.append(cfgTargets->query().queryProp(NULL));
+
+#ifdef _CONTAINERIZED
+    initContainerRoxieTargets(connMap);
+#else
+    initBareMetalRoxieTargets(connMap, serviceTree, daliAddress.str());
+#endif
     translator = new wsEclTypeTranslator();
 
     Owned<IPropertyTreeIterator> xsltProps = serviceTree->getElements("xslt*");
@@ -332,6 +360,28 @@ void CWsEclBinding::getNavigationData(IEspContext &context, IPropertyTree & data
     ensureNavDynFolder(data, "Targets", "Targets", "root=true", NULL);
 }
 
+static IStringIterator *getContainerTargetClusters()
+{
+    Owned<CStringArrayIterator> ret = new CStringArrayIterator;
+    Owned<IPropertyTreeIterator> queues = queryComponentConfig().getElements("queues");
+    ForEach(*queues)
+    {
+        IPropertyTree &queue = queues->query();
+        const char *qName = queue.queryProp("@name");
+        if (!isEmptyString(qName))
+            ret->append_unique(qName);
+    }
+    Owned<IPropertyTreeIterator> services = queryComponentConfig().getElements("services[@type='roxie']");
+    ForEach(*services)
+    {
+        IPropertyTree &service = services->query();
+        const char *targetName = service.queryProp("@target");
+        if (!isEmptyString(targetName))
+            ret->append_unique(targetName);
+    }
+    return ret.getClear();
+}
+
 void CWsEclBinding::getRootNavigationFolders(IEspContext &context, IPropertyTree & data)
 {
     DBGLOG("CScrubbedXmlBinding::getNavigationData");
@@ -343,7 +393,11 @@ void CWsEclBinding::getRootNavigationFolders(IEspContext &context, IPropertyTree
     data.addProp("@action", "NavMenuEvent");
     data.addProp("@appName", "WsECL 3.0");
 
+#ifdef _CONTAINERIZED
+    Owned<IStringIterator> envTargets = getContainerTargetClusters();
+#else
     Owned<IStringIterator> envTargets = getTargetClusters(NULL, NULL);
+#endif
 
     SCMStringBuffer target;
     ForEach(*envTargets)
@@ -2142,13 +2196,12 @@ int CWsEclBinding::onSubmitQueryOutputView(IEspContext &context, CHttpRequest* r
     StringBuffer status;
     StringBuffer html;
 
-    SCMStringBuffer clustertype;
-    wu->getDebugValue("targetclustertype", clustertype);
-
     StringBuffer xsltfile(getCFD());
     xsltfile.append("xslt/wsecl3_result.xslt");
     const char *view = context.queryRequestParameters()->queryProp("view");
-    if (!forceCreateWorkunit && strieq(clustertype.str(), "roxie"))
+
+    bool callRoxieQuery = !forceCreateWorkunit && nullptr!=wsecl->connMap.getValue(wsinfo.qsetname.get());
+    if (callRoxieQuery)
     {
         sendRoxieRequest(wsinfo.qsetname.get(), soapmsg, output, status, wsinfo.queryname, false, "text/xml", request);
         Owned<IWuWebView> web = createWuWebView(*wu, wsinfo.qsetname.get(), wsinfo.queryname.get(), getCFD(), true, queryXsltConfig());

+ 4 - 4
esp/xslt/wsecl3_jsontest.xsl

@@ -38,12 +38,12 @@
     <html>
       <head>
         <title>JSON Test Page</title>
-        <link rel="shortcut icon" href="files_/img/affinity_favicon_1.ico" />
-        <link rel="stylesheet" type="text/css" href="files_/yui/build/fonts/fonts-min.css" />
-        <link rel="stylesheet" type="text/css" href="files_/css/espdefault.css" />
+        <link rel="shortcut icon" href="/esp/files/img/affinity_favicon_1.ico" />
+        <link rel="stylesheet" type="text/css" href="/esp/files/yui/build/fonts/fonts-min.css" />
+        <link rel="stylesheet" type="text/css" href="/esp/files/css/espdefault.css" />
 
         <script>dojoConfig = {async:true, parseOnLoad:false}</script>
-        <script src="files_/dist/dojoLib.eclwatch.js"></script>
+        <script src="/esp/files/dist/dojoLib.eclwatch.js"></script>
     </head>
     <body class="yui-skin-sam" id="body">
       <h3>

+ 25 - 0
helm/hpcc/templates/_helpers.tpl

@@ -317,3 +317,28 @@ Generate instance queue names
  {{- end }}
 {{- end -}}
 {{- end -}}
+
+{{/*
+Generate list of available services
+*/}}
+{{- define "hpcc.generateConfigMapServices" -}}
+{{- range $roxie := $.Values.roxie -}}
+ {{- if not $roxie.disabled -}}
+  {{- range $service := $roxie.services -}}
+   {{- if ne (int $service.port) 0 -}}
+- name: {{ $service.name }}
+  type: roxie
+  port: {{ $service.port }}
+  target: {{ $roxie.name }}
+   {{- end -}}
+  {{- end }}
+{{ end -}}
+{{- end -}}
+{{- range $esp := $.Values.esp -}}
+- name: {{ $esp.name }}
+  type: {{ $esp.application }}
+  port: {{ $esp.servicePort }}
+  tls: {{ $esp.tls }}
+  public: {{ $esp.public }}
+{{ end -}}
+{{- end -}}

+ 2 - 0
helm/hpcc/templates/esp.yaml

@@ -49,6 +49,8 @@ data:
 {{- include "hpcc.generateLoggingConfig" (dict "root" $ "me" .) | indent 6 }}
       queues:
 {{ include "hpcc.generateConfigMapQueues" $ | indent 6 }}
+      services:
+{{ include "hpcc.generateConfigMapServices" $ | indent 6 }}
     global:
 {{ include "hpcc.generateGlobalConfigMap" $ | indent 6 }}
 ---

+ 2 - 0
helm/hpcc/templates/localroxie.yaml

@@ -63,6 +63,8 @@ apiVersion: v1
 kind: Service
 metadata:
   name: {{ $name | quote }}
+  labels:
+    type: roxie-service
 spec:
   ports:
   - port: {{ $service.port }}

+ 3 - 2
helm/hpcc/templates/roxie.yaml

@@ -37,11 +37,12 @@ spec:
 
 {{- range $service := $roxie.services }}
 {{- if ne (int $service.port)  0 }}
-{{- $name := printf "%s-%s" $roxie.name $service.name }}
 apiVersion: v1
 kind: Service
 metadata:
-  name: {{ $name | quote }}
+  name: {{ $service.name | quote }}
+  labels:
+    type: roxie-service
 spec:
   ports:
   - port: {{ $service.port }}

+ 5 - 7
helm/hpcc/values.yaml

@@ -97,9 +97,9 @@ eclagent:
   ## type may be 'hthor' (the default) or 'roxie', to specify that the roxie engine rather than the hthor engine should be used for eclagent workunit processing
   type: hthor
 
-- name: roxie
+- name: roxie-workunit
   replicas: 1
-  prefix: roxie
+  prefix: roxie_workunit
   maxActive: 20
   useChildProcesses: true
   type: roxie
@@ -145,17 +145,15 @@ esp:
   servicePort: 8002
 
 roxie:
-- name: roxie-cluster
+- name: roxie
   disabled: false
-  prefix: roxiecluster
+  prefix: roxie
   services:
-  - name: query
+  - name: roxie
     port: 9876
     listenQueue: 200
     numThreads: 0
     external: true
-  - name: on-demand
-    port: 0
   numChannels: 2
   ## Set serverReplicas to indicate a separate replicaSet of roxie servers, with slave nodes not acting as servers
   serverReplicas: 0

+ 1 - 0
system/jlib/jutil.hpp

@@ -268,6 +268,7 @@ class jlib_decl CStringArrayIterator : implements CInterfaceOf<IStringIterator>
     StringArray strings;
 public:
     void append(const char *str) { strings.append(str); }
+    void append_unique(const char *str) { strings.appendUniq(str); }
     virtual bool first() { idx = 0; return strings.isItem(idx); }
     virtual bool next() { idx ++; return strings.isItem(idx); }
     virtual bool isValid() { return strings.isItem(idx); }