Преглед изворни кода

Merge pull request #905 from afishbeck/add_activate

Refactor WsWorkunits Query and Alias actions
Reviewed-by: Gavin Halliday <ghalliday@hpccsystems.com>
Gavin Halliday пре 13 година
родитељ
комит
4d43b0be34

+ 30 - 0
ecl/eclcmd/eclcmd_common.cpp

@@ -217,3 +217,33 @@ StringBuffer &EclObjectParameter::getDescription(StringBuffer &s)
 {
     return s.append(queryTypeName()).append(' ').append(value.get());
 }
+
+eclCmdOptionMatchIndicator EclCmdCommon::matchCommandLineOption(ArgvIterator &iter, bool finalAttempt)
+{
+    bool boolValue;
+    if (iter.matchFlag(boolValue, ECLOPT_VERSION))
+    {
+        fprintf(stdout, "%s\n", BUILD_TAG);
+        return EclCmdOptionCompletion;
+    }
+    if (iter.matchOption(optServer, ECLOPT_SERVER))
+        return EclCmdOptionMatch;
+    if (iter.matchOption(optPort, ECLOPT_PORT))
+        return EclCmdOptionMatch;
+    if (iter.matchOption(optUsername, ECLOPT_USERNAME))
+        return EclCmdOptionMatch;
+    if (iter.matchOption(optPassword, ECLOPT_PASSWORD))
+        return EclCmdOptionMatch;
+    if (finalAttempt)
+        fprintf(stderr, "\n%s option not recognized\n", iter.query());
+    return EclCmdOptionNoMatch;
+}
+
+bool EclCmdCommon::finalizeOptions(IProperties *globals)
+{
+    extractEclCmdOption(optServer, globals, ECLOPT_SERVER_ENV, ECLOPT_SERVER_INI, ECLOPT_SERVER_DEFAULT, NULL);
+    extractEclCmdOption(optPort, globals, ECLOPT_PORT_ENV, ECLOPT_PORT_INI, ECLOPT_PORT_DEFAULT, NULL);
+    extractEclCmdOption(optUsername, globals, ECLOPT_USERNAME_ENV, ECLOPT_USERNAME_INI, NULL, NULL);
+    extractEclCmdOption(optPassword, globals, ECLOPT_PASSWORD_ENV, ECLOPT_PASSWORD_INI, NULL, NULL);
+    return true;
+}

+ 4 - 26
ecl/eclcmd/eclcmd_common.hpp

@@ -57,6 +57,7 @@ typedef IEclCommand *(*EclCommandFactory)(const char *cmdname);
 #define ECLOPT_CLUSTER "--cluster"
 #define ECLOPT_NAME "--name"
 #define ECLOPT_ACTIVATE "--activate"
+#define ECLOPT_QUERYSET "--queryset"
 #define ECLOPT_VERSION "--version"
 
 bool extractEclCmdOption(StringBuffer & option, IProperties * globals, const char * envName, const char * propertyName, const char * defaultPrefix, const char * defaultSuffix);
@@ -102,32 +103,9 @@ public:
     EclCmdCommon()
     {
     }
-    virtual eclCmdOptionMatchIndicator matchCommandLineOption(ArgvIterator &iter)
-    {
-        bool boolValue;
-        if (iter.matchFlag(boolValue, ECLOPT_VERSION))
-        {
-            fprintf(stdout, "%s\n", BUILD_TAG);
-            return EclCmdOptionCompletion;
-        }
-        if (iter.matchOption(optServer, ECLOPT_SERVER))
-            return EclCmdOptionMatch;
-        if (iter.matchOption(optPort, ECLOPT_PORT))
-            return EclCmdOptionMatch;
-        if (iter.matchOption(optUsername, ECLOPT_USERNAME))
-            return EclCmdOptionMatch;
-        if (iter.matchOption(optPassword, ECLOPT_PASSWORD))
-            return EclCmdOptionMatch;
-        return EclCmdOptionNoMatch;
-    }
-    virtual bool finalizeOptions(IProperties *globals)
-    {
-        extractEclCmdOption(optServer, globals, ECLOPT_SERVER_ENV, ECLOPT_SERVER_INI, ECLOPT_SERVER_DEFAULT, NULL);
-        extractEclCmdOption(optPort, globals, ECLOPT_PORT_ENV, ECLOPT_PORT_INI, ECLOPT_PORT_DEFAULT, NULL);
-        extractEclCmdOption(optUsername, globals, ECLOPT_USERNAME_ENV, ECLOPT_USERNAME_INI, NULL, NULL);
-        extractEclCmdOption(optPassword, globals, ECLOPT_PASSWORD_ENV, ECLOPT_PASSWORD_INI, NULL, NULL);
-        return true;
-    }
+    virtual eclCmdOptionMatchIndicator matchCommandLineOption(ArgvIterator &iter, bool finalAttempt=false);
+    virtual bool finalizeOptions(IProperties *globals);
+
     virtual void usage()
     {
         fprintf(stdout,

+ 244 - 68
ecl/eclcmd/eclcmd_core.cpp

@@ -70,16 +70,8 @@ public:
                 continue;
             if (iter.matchOption(optName, ECLOPT_NAME))
                 continue;
-            switch (EclCmdCommon::matchCommandLineOption(iter))
-            {
-                case EclCmdOptionNoMatch:
-                    fprintf(stderr, "\n%s option not recognized\n", arg);
-                    return false;
-                case EclCmdOptionCompletion:
-                    return false;
-                case EclCmdOptionMatch:
-                    break;
-            }
+            if (EclCmdCommon::matchCommandLineOption(iter, true)!=EclCmdOptionMatch)
+                return false;
         }
         return true;
     }
@@ -124,53 +116,44 @@ public:
     virtual int processCMD()
     {
         StringBuffer s;
-        if (optObj.type==eclObjTypeUnknown)
-            fprintf(stderr, "\nCan't determine content type of argument %s\n", optObj.value.sget());
-        else if (optObj.type==eclObjSource)
-            fprintf(stderr, "\nDirect deployment of ECL source is not yet supported\n");
-        else if (optObj.type==eclObjWuid || optObj.type==eclObjQueryId)
-            fprintf(stderr, "\nRemote objects already deployed %s\n", optObj.getDescription(s).str());
-        else
+        fprintf(stdout, "\nDeploying %s\n", optObj.getDescription(s).str());
+        Owned<IClientWsWorkunits> client = createWsWorkunitsClient();
+        VStringBuffer url("http://%s:%s/WsWorkunits", optServer.sget(), optPort.sget());
+        client->addServiceUrl(url.str());
+        if (optUsername.length())
+            client->setUsernameToken(optUsername.get(), optPassword.sget(), NULL);
+        Owned<IClientWUDeployWorkunitRequest> req = client->createWUDeployWorkunitRequest();
+        switch (optObj.type)
         {
-            fprintf(stdout, "\nDeploying %s\n", optObj.getDescription(s).str());
-            Owned<IClientWsWorkunits> client = createWsWorkunitsClient();
-            VStringBuffer url("http://%s:%s/WsWorkunits", optServer.sget(), optPort.sget());
-            client->addServiceUrl(url.str());
-            if (optUsername.length())
-                client->setUsernameToken(optUsername.get(), optPassword.sget(), NULL);
-            Owned<IClientWUDeployWorkunitRequest> req = client->createWUDeployWorkunitRequest();
-            switch (optObj.type)
+            case eclObjArchive:
             {
-                case eclObjArchive:
-                {
-                    req->setObjType("archive");
-                    break;
-                }
-                case eclObjSharedObject:
-                {
-                    req->setObjType("shared_object");
-                    break;
-                }
+                req->setObjType("archive");
+                break;
             }
-            MemoryBuffer mb;
-            Owned<IFile> file = createIFile(optObj.value.sget());
-            Owned<IFileIO> io = file->open(IFOread);
-            read(io, 0, (size32_t)file->size(), mb);
-            if (optName.length())
-                req->setName(optName.get());
-            if (optCluster.length())
-                req->setCluster(optCluster.get());
-            req->setFileName(optObj.value.sget());
-            req->setObject(mb);
-            Owned<IClientWUDeployWorkunitResponse> resp = client->WUDeployWorkunit(req);
-            if (resp->getExceptions().ordinality())
-                outputMultiExceptions(resp->getExceptions());
-            const char *wuid = resp->getWorkunit().getWuid();
-            if (wuid && *wuid)
+            case eclObjSharedObject:
             {
-                fprintf(stdout, "\nDeployed\nwuid: %s\nstate: %s\n", wuid, resp->getWorkunit().getState());
+                req->setObjType("shared_object");
+                break;
             }
         }
+        MemoryBuffer mb;
+        Owned<IFile> file = createIFile(optObj.value.sget());
+        Owned<IFileIO> io = file->open(IFOread);
+        read(io, 0, (size32_t)file->size(), mb);
+        if (optName.length())
+            req->setName(optName.get());
+        if (optCluster.length())
+            req->setCluster(optCluster.get());
+        req->setFileName(optObj.value.sget());
+        req->setObject(mb);
+        Owned<IClientWUDeployWorkunitResponse> resp = client->WUDeployWorkunit(req);
+        if (resp->getExceptions().ordinality())
+            outputMultiExceptions(resp->getExceptions());
+        const char *wuid = resp->getWorkunit().getWuid();
+        if (wuid && *wuid)
+        {
+            fprintf(stdout, "Deployed\nwuid: %s\nstate: %s\n", wuid, resp->getWorkunit().getState());
+        }
         return 0;
     }
     virtual void usage()
@@ -179,6 +162,9 @@ public:
             "ecl deploy --cluster=<cluster> --name=<name> <archive>\n"
             "ecl deploy [--cluster=<cluster>] [--name=<name>] <so|dll>\n\n"
             "   Options:\n"
+            "      <archive>            ecl archive to deploy\n"
+            "      <so|dll>             dll or shared object to deploy\n"
+            "      --name=<name>        workunit job name\n"
             "      --cluster=<cluster>  cluster to associate workunit with\n"
             "      --name=<name>        workunit job name\n"
         );
@@ -228,16 +214,8 @@ public:
                 activateSet=true;
                 continue;
             }
-            switch (EclCmdCommon::matchCommandLineOption(iter))
-            {
-                case EclCmdOptionNoMatch:
-                    fprintf(stderr, "\n%s option not recognized\n", arg);
-                    return false;
-                case EclCmdOptionCompletion:
-                    return false;
-                case EclCmdOptionMatch:
-                    break;
-            }
+            if (EclCmdCommon::matchCommandLineOption(iter, true)!=EclCmdOptionMatch)
+                return false;
         }
         return true;
     }
@@ -256,13 +234,6 @@ public:
     }
     virtual int processCMD()
     {
-        StringBuffer s;
-        if (!optWuid.length())
-        {
-            fprintf(stderr, "\nError: wuid parameter required\n");
-            return 1;
-        }
-
         fprintf(stdout, "\nPublishing %s\n", optWuid.get());
         Owned<IClientWsWorkunits> client = createWsWorkunitsClient();
         VStringBuffer url("http://%s:%s/WsWorkunits", optServer.sget(), optPort.sget());
@@ -292,6 +263,7 @@ public:
         fprintf(stdout,"\nUsage:\n\n"
             "ecl publish [--cluster=<cluster>][--name=<name>][--activate] <wuid>\n\n"
             "   Options:\n"
+            "      <wuid>               workunit to publish\n"
             "      --cluster=<cluster>  cluster to publish workunit to\n"
             "                           (defaults to cluster defined inside workunit)\n"
             "      --name=<name>        query name to use for published workunit\n"
@@ -307,6 +279,206 @@ private:
     bool activateSet;
 };
 
+class EclCmdActivate : public EclCmdCommon
+{
+public:
+    EclCmdActivate()
+    {
+    }
+    virtual bool parseCommandLineOptions(ArgvIterator &iter)
+    {
+        if (iter.done())
+        {
+            usage();
+            return false;
+        }
+
+        for (; !iter.done(); iter.next())
+        {
+            const char *arg = iter.query();
+            if (*arg!='-')
+            {
+                if (optQueryId.length())
+                {
+                    fprintf(stderr, "\nmultiple query ids (%s and %s) not supported\n", optQueryId.sget(), arg);
+                    return false;
+                }
+                optQueryId.set(arg);
+                continue;
+            }
+            if (iter.matchOption(optQuerySet, ECLOPT_QUERYSET))
+                continue;
+            if (EclCmdCommon::matchCommandLineOption(iter, true)!=EclCmdOptionMatch)
+                return false;
+        }
+        return true;
+    }
+    virtual bool finalizeOptions(IProperties *globals)
+    {
+        if (!EclCmdCommon::finalizeOptions(globals))
+            return false;
+        if (optQuerySet.isEmpty())
+        {
+            fprintf(stderr, "\nError: queryset parameter required\n");
+            return false;
+        }
+        if (optQueryId.isEmpty())
+        {
+            fprintf(stderr, "\nError: queryid parameter required\n");
+            return false;
+        }
+        return true;
+    }
+    virtual int processCMD()
+    {
+        Owned<IClientWsWorkunits> client = createWsWorkunitsClient();
+        VStringBuffer url("http://%s:%s/WsWorkunits", optServer.sget(), optPort.sget());
+        client->addServiceUrl(url.str());
+        if (optUsername.length())
+            client->setUsernameToken(optUsername.get(), optPassword.sget(), NULL);
+
+        Owned<IClientWUQuerySetQueryActionRequest> req = client->createWUQuerysetQueryActionRequest();
+        IArrayOf<IEspQuerySetQueryActionItem> queries;
+        Owned<IEspQuerySetQueryActionItem> item = createQuerySetQueryActionItem();
+        item->setQueryId(optQueryId.get());
+        queries.append(*item.getClear());
+        req->setQueries(queries);
+
+        req->setAction("Activate");
+        req->setQuerySetName(optQuerySet.get());
+
+        Owned<IClientWUQuerySetQueryActionResponse> resp = client->WUQuerysetQueryAction(req);
+        IArrayOf<IConstQuerySetQueryActionResult> &results = resp->getResults();
+        if (resp->getExceptions().ordinality())
+            outputMultiExceptions(resp->getExceptions());
+        else if (results.empty())
+            fprintf(stderr, "\nError Empty Result!\n");
+        else
+        {
+            IConstQuerySetQueryActionResult &item = results.item(0);
+            if (item.getSuccess())
+                fprintf(stdout, "\nActivated %s/%s\n", optQuerySet.sget(), optQueryId.sget());
+            else if (item.getCode()|| item.getMessage())
+                fprintf(stderr, "Error (%d) %s\n", item.getCode(), item.getMessage());
+        }
+        return 0;
+    }
+    virtual void usage()
+    {
+        fprintf(stdout,"\nUsage:\n\n"
+            "ecl activate --queryset=<queryset> <queryid>\n"
+            "   Options:\n"
+            "      <queryid>             queryid of query to activate\n"
+            "      --queryset=<queryset> name of queryset containing query to activate\n"
+        );
+        EclCmdCommon::usage();
+    }
+private:
+    StringAttr optQuerySet;
+    StringAttr optQueryId;
+};
+
+
+class EclCmdDeactivate : public EclCmdCommon
+{
+public:
+    EclCmdDeactivate()
+    {
+    }
+    virtual bool parseCommandLineOptions(ArgvIterator &iter)
+    {
+        if (iter.done())
+        {
+            usage();
+            return false;
+        }
+
+        for (; !iter.done(); iter.next())
+        {
+            const char *arg = iter.query();
+            if (*arg!='-')
+            {
+                if (optAlias.length())
+                {
+                    fprintf(stderr, "\nmultiple aliases not supported\n");
+                    return false;
+                }
+                optAlias.set(arg);
+                continue;
+            }
+            if (iter.matchOption(optQuerySet, ECLOPT_QUERYSET))
+                continue;
+            if (EclCmdCommon::matchCommandLineOption(iter, true)!=EclCmdOptionMatch)
+                return false;
+        }
+        return true;
+    }
+    virtual bool finalizeOptions(IProperties *globals)
+    {
+        if (!EclCmdCommon::finalizeOptions(globals))
+            return false;
+        if (optQuerySet.isEmpty())
+        {
+            fprintf(stderr, "\nError: queryset parameter required\n");
+            return false;
+        }
+        if (optAlias.isEmpty())
+        {
+            fprintf(stderr, "\nError: alias parameter required\n");
+            return false;
+        }
+        return true;
+    }
+    virtual int processCMD()
+    {
+        StringBuffer s;
+        Owned<IClientWsWorkunits> client = createWsWorkunitsClient();
+        VStringBuffer url("http://%s:%s/WsWorkunits", optServer.sget(), optPort.sget());
+        client->addServiceUrl(url.str());
+        if (optUsername.length())
+            client->setUsernameToken(optUsername.get(), optPassword.sget(), NULL);
+
+        Owned<IClientWUQuerySetAliasActionRequest> req = client->createWUQuerysetAliasActionRequest();
+        IArrayOf<IEspQuerySetAliasActionItem> aliases;
+        Owned<IEspQuerySetAliasActionItem> item = createQuerySetAliasActionItem();
+        item->setName(optAlias.get());
+        aliases.append(*item.getClear());
+        req->setAliases(aliases);
+
+        req->setAction("Deactivate");
+        req->setQuerySetName(optQuerySet.get());
+
+        Owned<IClientWUQuerySetAliasActionResponse> resp = client->WUQuerysetAliasAction(req);
+        IArrayOf<IConstQuerySetAliasActionResult> &results = resp->getResults();
+        if (resp->getExceptions().ordinality())
+            outputMultiExceptions(resp->getExceptions());
+        else if (results.empty())
+            fprintf(stderr, "\nError Empty Result!\n");
+        else
+        {
+            IConstQuerySetAliasActionResult &item = results.item(0);
+            if (item.getSuccess())
+                fprintf(stdout, "Deactivated alias %s/%s\n", optQuerySet.sget(), optAlias.sget());
+            else if (item.getCode()|| item.getMessage())
+                fprintf(stderr, "Error (%d) %s\n", item.getCode(), item.getMessage());
+        }
+        return 0;
+    }
+    virtual void usage()
+    {
+        fprintf(stdout,"\nUsage:\n\n"
+            "ecl deactivate --queryset=<queryset> <alias>\n"
+            "   Options:\n"
+            "      <alias>               alias to deactivate (delete)\n"
+            "      queryset=<queryset>   queryset containing alias to deactivate\n"
+        );
+        EclCmdCommon::usage();
+    }
+private:
+    StringAttr optQuerySet;
+    StringAttr optAlias;
+};
+
 //=========================================================================================
 
 IEclCommand *createCoreEclCommand(const char *cmdname)
@@ -317,5 +489,9 @@ IEclCommand *createCoreEclCommand(const char *cmdname)
         return new EclCmdDeploy();
     if (strieq(cmdname, "publish"))
         return new EclCmdPublish();
+    if (strieq(cmdname, "activate"))
+        return new EclCmdActivate();
+    if (strieq(cmdname, "deactivate"))
+        return new EclCmdDeactivate();
     return NULL;
 }

+ 19 - 14
esp/eclwatch/ws_XSLT/WUQuerysetQueries.xslt

@@ -56,12 +56,15 @@
                             var sortableTable = null;
 
               function deleteQueries() {
-                actionWorkunits('Remove');
+                actionWorkunits('Delete');
               }
 
               function toggleQueries() {
                 actionWorkunits('ToggleSuspend');
               }
+              function activateQueries() {
+                actionWorkunits('Activate');
+              }
 
               function actionWorkunits(Action) {
                   var connectionCallback = {
@@ -76,37 +79,35 @@
                       }
                   };
 
-                  var postBody = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding" xmlns="http://webservices.seisint.com/ws_roxieconfig"><soap:Body>' + getQueryActions(Action) + '</soap:Body></soap:Envelope>';
+                  var postBody = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding" xmlns="http://webservices.seisint.com/WsWorkunits"><soap:Body>' + getQueryActions(Action) + '</soap:Body></soap:Envelope>';
 
-                  YAHOO.util.Connect.initHeader("SOAPAction", "/WsWorkunits/WUQuerysetActionQueries?");
+                  YAHOO.util.Connect.initHeader("SOAPAction", "/WsWorkunits/WUQuerysetQueryAction?");
                   YAHOO.util.Connect.initHeader("Content-Type", "text/xml");
                   YAHOO.util.Connect._use_default_post_header = false;
 
                   var getXML = YAHOO.util.Connect.asyncRequest("POST",
-                          "/WsWorkunits/WUQuerysetActionQueries",
+                          "/WsWorkunits/WUQuerysetQueryAction",
                           connectionCallback, postBody);
                   return;
 
               }
 
               function getQueryActions(Action) {
-                  var remove = Action == 'Remove' ? 1 : 0;
-                  var toggleSuspend = Action == 'ToggleSuspend' ? 1 : 0;
-                  var soapXML = '<WUQuerysetActionQueries><QuerySetName>' + querySet + '</QuerySetName><Remove>' + remove + '</Remove><ToggleSuspend>' + toggleSuspend + '</ToggleSuspend><QuerysetQueryActions>';
+                  var soapXML = '<WUQuerysetQueryAction><QuerySetName>' + querySet + '</QuerySetName><Action>' + Action + '</Action><Queries>';
 
                   // get records and iterate.
 
                   var selectedRows = queryDataTable.getSelectedRows();
                   for (var i = 0; i < selectedRows.length; i++) {
                      var record = queryDataTable.getRecord(selectedRows[i]);
-                     soapXML += '<QuerysetQueryAction><Id>' + record.getData('Id') + '</Id><Suspended>' + record.getData('Suspended') + '</Suspended></QuerysetQueryAction>';
+                     soapXML += '<QuerySetQueryActionItem><QueryId>' + record.getData('Id') + '</QueryId><ClientState><Suspended>' + record.getData('Suspended') + '</Suspended></ClientState></QuerySetQueryActionItem>';
                   }
-                  soapXML += '</QuerysetQueryActions></WUQuerysetActionQueries>';
+                  soapXML += '</Queries></WUQuerysetQueryAction>';
                   return soapXML;
               }
 
               function deleteAliases() {
-                actionAliases('Remove');
+                actionAliases('Deactivate');
               }
 
               function actionAliases(Action) {
@@ -136,17 +137,16 @@
               }
 
               function getAliasActions(Action) {
-                  var remove = Action == 'Remove' ? 1 : 1;
-                  var soapXML = '<WUQuerysetActionAliases><QuerySetName>' + querySet + '</QuerySetName><Remove>' + remove + '</Remove><QuerysetAliasActions>';
+                  var soapXML = '<WUQuerysetAliasAction><QuerySetName>' + querySet + '</QuerySetName><Action>' + Action + '</Action><Aliases>';
 
                   // get records and iterate.
 
                   var selectedRows = aliasDataTable.getSelectedRows();
                   for (var i = 0; i < selectedRows.length; i++) {
                      var record = aliasDataTable.getRecord(selectedRows[i]);
-                     soapXML += '<QuerysetAliasAction><Id>' + record.getData('Id') + '</Id></QuerysetAliasAction>';
+                     soapXML += '<Alias><Name>' + record.getData('Name') + '</Name></Alias>';
                   }
-                  soapXML += '</QuerysetAliasActions></WUQuerysetActionAliases>';
+                  soapXML += '</Alias></WUQuerysetAliasAction>';
                   return soapXML;
               }
 
@@ -261,6 +261,11 @@
                   <button type="button" name="ToggleSuspendButton" onclick="toggleQueries();">Toggle Suspend</button>
                 </em>
               </span>
+              <span id="ActivateButton" class="yui-button yui-push-button">
+                <em class="first-child">
+                    <button type="button" name="ActivateButton" onclick="activateQueries();">Activate</button>
+                </em>
+             </span>
             </div>
             <div>
               <div id="aliasdiv">&#160;</div>

+ 58 - 27
esp/scm/ws_workunits.ecm

@@ -1072,49 +1072,80 @@ ESPresponse [exceptions_inline] WUQuerySetDetailsResponse
     ESParray<ESPstruct QuerySetAlias> QuerysetAliases;
 };
 
-ESPStruct QuerySetQueryAction
+ESPenum QuerySetQueryActionTypes : string
+{
+    Suspend("Suspend"),
+    Unsuspend("Unsuspend"),
+    ToggleSuspend("ToggleSuspend"),
+    Activate("Activate"),
+    Delete("Delete"),
+    RemoveAllAliases("RemoveAllAliases")
+};
+
+ESPStruct QuerySetQueryClientState
 {
-    string Id;
-    string Name;
     bool Suspended;
-    string Status;
 };
 
-ESPrequest WUQuerySetActionQueriesRequest
+ESPStruct QuerySetQueryActionItem
 {
-    string  QuerySetName;
-    bool Remove(false);
-    bool ToggleSuspend(false);
-    ESParray<ESPstruct QuerySetQueryAction> QuerysetQueryActions;
+    string QueryId;
+    ESPstruct QuerySetQueryClientState ClientState;
 };
 
-ESPresponse [exceptions_inline] WUQuerySetActionQueriesResponse
+ESPrequest WUQuerySetQueryActionRequest
 {
-    string  QuerySetName;
-    bool Remove;
-    bool ToggleSuspend;
-    ESParray<ESPstruct QuerySetQueryAction> QuerysetQueryActions;
+    ESPenum QuerySetQueryActionTypes Action;
+    string QuerySetName;
+    ESParray<ESPstruct QuerySetQueryActionItem, Query> Queries;
 };
 
-ESPStruct QuerySetAliasAction
+ESPStruct QuerySetQueryActionResult
+{
+    string QueryId;
+    bool Suspended;
+    bool Success;
+    int Code;
+    string Message;
+};
+
+ESPresponse [exceptions_inline] WUQuerySetQueryActionResponse
+{
+    ESPenum QuerySetQueryActionTypes Action;
+    string QuerySetName;
+    ESParray<ESPstruct QuerySetQueryActionResult, Result> Results;
+};
+
+ESPenum QuerySetAliasActionTypes : string
+{
+    Deactivate("Deactivate")
+};
+
+ESPStruct QuerySetAliasActionItem
 {
-    string Id;
     string Name;
-    string Status;
 };
 
-ESPrequest WUQuerySetActionAliasesRequest
+ESPrequest WUQuerySetAliasActionRequest
 {
-    string  QuerySetName;
-    bool Remove(false);
-    ESParray<ESPstruct QuerySetAliasAction> QuerysetAliasActions;
+    ESPenum QuerySetAliasActionTypes Action;
+    string QuerySetName;
+    ESParray<ESPstruct QuerySetAliasActionItem, Alias> Aliases;
 };
 
-ESPresponse [exceptions_inline] WUQuerySetActionAliasesResponse
+ESPStruct QuerySetAliasActionResult
 {
-    string  QuerySetName;
-    bool Remove;
-    ESParray<ESPstruct QuerySetAliasAction> QuerysetAliasActions;
+    string Name;
+    bool Success;
+    int Code;
+    string Message;
+};
+
+ESPresponse [exceptions_inline] WUQuerySetAliasActionResponse
+{
+    ESPenum QuerySetAliasActionTypes Action;
+    string QuerySetName;
+    ESParray<ESPstruct QuerySetAliasActionResult, Result> Results;
 };
 
 ESPservice [
@@ -1177,8 +1208,8 @@ ESPservice [
     ESPmethod [resp_xsl_default("/esp/xslt/WUPublishWorkunit.xslt")] WUPublishWorkunit(WUPublishWorkunitRequest, WUPublishWorkunitResponse);
     ESPmethod [resp_xsl_default("/esp/xslt/WUQuerysets.xslt")] WUQuerysets(WUQuerysetsRequest, WUQuerysetsResponse);
     ESPmethod [resp_xsl_default("/esp/xslt/WUQuerysetQueries.xslt")] WUQuerysetDetails(WUQuerySetDetailsRequest, WUQuerySetDetailsResponse);
-    ESPmethod WUQuerysetActionQueries(WUQuerySetActionQueriesRequest, WUQuerySetActionQueriesResponse);
-    ESPmethod WUQuerysetActionAliases(WUQuerySetActionAliasesRequest, WUQuerySetActionAliasesResponse);
+    ESPmethod WUQuerysetQueryAction(WUQuerySetQueryActionRequest, WUQuerySetQueryActionResponse);
+    ESPmethod WUQuerysetAliasAction(WUQuerySetAliasActionRequest, WUQuerySetAliasActionResponse);
     ESPmethod [resp_xsl_default("/esp/xslt/WUCopyLogicalFiles.xslt")] WUCopyLogicalFiles(WUCopyLogicalFilesRequest, WUCopyLogicalFilesResponse);
 };
 

+ 79 - 40
esp/services/ws_workunits/ws_workunitsQuerySets.cpp

@@ -309,68 +309,107 @@ bool CWsWorkunitsEx::onWUQuerysetDetails(IEspContext &context, IEspWUQuerySetDet
     return true;
 }
 
-bool CWsWorkunitsEx::onWUQuerysetActionQueries(IEspContext &context, IEspWUQuerySetActionQueriesRequest & req, IEspWUQuerySetActionQueriesResponse & resp)
+bool CWsWorkunitsEx::onWUQuerysetQueryAction(IEspContext &context, IEspWUQuerySetQueryActionRequest & req, IEspWUQuerySetQueryActionResponse & resp)
 {
     resp.setQuerySetName(req.getQuerySetName());
-    resp.setRemove(req.getRemove());
+    resp.setAction(req.getAction());
 
-    Owned<IPropertyTree> queryRegistry = getQueryRegistry(req.getQuerySetName(), false);
+    if (isEmpty(req.getQuerySetName()))
+        throw MakeStringException(ECLWATCH_MISSING_PARAMS, "Queryset name required");
+    Owned<IPropertyTree> queryset = getQueryRegistry(req.getQuerySetName(), true);
+    if (!queryset)
+        throw MakeStringException(ECLWATCH_QUERYSET_NOT_FOUND, "Queryset %s not found", req.getQuerySetName());
 
-    IArrayOf<IEspQuerySetQueryAction> actions;
-    ForEachItemIn(qa, req.getQuerysetQueryActions())
+    IArrayOf<IEspQuerySetQueryActionResult> results;
+    ForEachItemIn(i, req.getQueries())
     {
-        IConstQuerySetQueryAction& item=req.getQuerysetQueryActions().item(qa);
-        if(notEmpty(item.getId()))
+        IConstQuerySetQueryActionItem& item=req.getQueries().item(i);
+        Owned<IEspQuerySetQueryActionResult> result = createQuerySetQueryActionResult();
+        try
         {
-            if (req.getRemove())
+            VStringBuffer xpath("Query[@id='%s']", item.getQueryId());
+            IPropertyTree *query = queryset->queryPropTree(xpath.str());
+            if (!query)
+                throw MakeStringException(ECLWATCH_QUERYID_NOT_FOUND, "Query %s/%s not found.", req.getQuerySetName(), item.getQueryId());
+            switch (req.getAction())
             {
-                removeAliasesFromNamedQuery(queryRegistry, item.getId());
-                removeNamedQuery(queryRegistry, item.getId());
-
-                Owned<IEspQuerySetQueryAction> action = createQuerySetQueryAction("", "");
-                action->setId(item.getId());
-                action->setStatus("Completed");
-                actions.append(*action.getClear());
-            }
-            if (req.getToggleSuspend())
-            {
-                setQuerySuspendedState(queryRegistry, item.getId(), !item.getSuspended());
-
-                Owned<IEspQuerySetQueryAction> action = createQuerySetQueryAction("", "");
-                action->setId(item.getId());
-                action->setStatus("Completed");
-                actions.append(*action.getClear());
+                case CQuerySetQueryActionTypes_ToggleSuspend:
+                    setQuerySuspendedState(queryset, item.getQueryId(), !item.getClientState().getSuspended());
+                    break;
+                case CQuerySetQueryActionTypes_Suspend:
+                    setQuerySuspendedState(queryset, item.getQueryId(), true);
+                    break;
+                case CQuerySetQueryActionTypes_Unsuspend:
+                    setQuerySuspendedState(queryset, item.getQueryId(), false);
+                    break;
+                case CQuerySetQueryActionTypes_Activate:
+                    setQueryAlias(queryset, query->queryProp("@name"), item.getQueryId());
+                    break;
+                case CQuerySetQueryActionTypes_Delete:
+                    removeAliasesFromNamedQuery(queryset, item.getQueryId());
+                    removeNamedQuery(queryset, item.getQueryId());
+                    break;
+                case CQuerySetQueryActionTypes_RemoveAllAliases:
+                    removeAliasesFromNamedQuery(queryset, item.getQueryId());
+                    break;
             }
+            result->setSuccess(true);
+            query = queryset->queryPropTree(xpath.str()); // refresh
+            if (query)
+                result->setSuspended(query->getPropBool("@suspended"));
         }
+        catch(IException *e)
+        {
+            StringBuffer msg;
+            result->setMessage(e->errorMessage(msg).str());
+            result->setCode(e->errorCode());
+            result->setSuccess(false);
+        }
+        results.append(*result.getClear());
     }
-    resp.setQuerysetQueryActions(actions);
+    resp.setResults(results);
     return true;
 }
 
-bool CWsWorkunitsEx::onWUQuerysetActionAliases(IEspContext &context, IEspWUQuerySetActionAliasesRequest & req, IEspWUQuerySetActionAliasesResponse & resp)
+bool CWsWorkunitsEx::onWUQuerysetAliasAction(IEspContext &context, IEspWUQuerySetAliasActionRequest &req, IEspWUQuerySetAliasActionResponse &resp)
 {
     resp.setQuerySetName(req.getQuerySetName());
-    resp.setRemove(req.getRemove());
+    resp.setAction(req.getAction());
 
-    Owned<IPropertyTree> queryRegistry = getQueryRegistry(req.getQuerySetName(), false);
+    if (isEmpty(req.getQuerySetName()))
+        throw MakeStringException(ECLWATCH_MISSING_PARAMS, "Queryset name required");
+    Owned<IPropertyTree> queryset = getQueryRegistry(req.getQuerySetName(), true);
+    if (!queryset)
+        throw MakeStringException(ECLWATCH_QUERYSET_NOT_FOUND, "Queryset %s not found", req.getQuerySetName());
 
-    IArrayOf<IEspQuerySetAliasAction> actions;
-    ForEachItemIn(aa, req.getQuerysetAliasActions())
+    IArrayOf<IEspQuerySetAliasActionResult> results;
+    ForEachItemIn(i, req.getAliases())
     {
-        IConstQuerySetAliasAction& item=req.getQuerysetAliasActions().item(aa);
-        if (req.getRemove())
+        IConstQuerySetAliasActionItem& item=req.getAliases().item(i);
+        Owned<IEspQuerySetAliasActionResult> result = createQuerySetAliasActionResult();
+        try
         {
-            if(notEmpty(item.getId()))
+            VStringBuffer xpath("Alias[@name='%s']", item.getName());
+            IPropertyTree *alias = queryset->queryPropTree(xpath.str());
+            if (!alias)
+                throw MakeStringException(ECLWATCH_ALIAS_NOT_FOUND, "Alias %s/%s not found.", req.getQuerySetName(), item.getName());
+            switch (req.getAction())
             {
-                removeAliasesFromNamedQuery(queryRegistry, item.getId());
-                Owned<IEspQuerySetAliasAction> action = createQuerySetAliasAction("", "");
-                action->setId(item.getId());
-                action->setStatus("Completed");
-                actions.append(*action.getClear());
-
+                case CQuerySetAliasActionTypes_Deactivate:
+                    removeQuerySetAlias(req.getQuerySetName(), item.getName());
+                    break;
             }
+            result->setSuccess(true);
+        }
+        catch(IException *e)
+        {
+            StringBuffer msg;
+            result->setMessage(e->errorMessage(msg).str());
+            result->setCode(e->errorCode());
+            result->setSuccess(false);
         }
+        results.append(*result.getClear());
     }
-    resp.setQuerysetAliasActions(actions);
+    resp.setResults(results);
     return true;
 }

+ 2 - 2
esp/services/ws_workunits/ws_workunitsService.hpp

@@ -42,8 +42,8 @@ public:
     bool onWUPublishWorkunit(IEspContext &context, IEspWUPublishWorkunitRequest & req, IEspWUPublishWorkunitResponse & resp);
     bool onWUQuerysets(IEspContext &context, IEspWUQuerysetsRequest & req, IEspWUQuerysetsResponse & resp);
     bool onWUQuerysetDetails(IEspContext &context, IEspWUQuerySetDetailsRequest & req, IEspWUQuerySetDetailsResponse & resp);
-    bool onWUQuerysetActionQueries(IEspContext &context, IEspWUQuerySetActionQueriesRequest & req, IEspWUQuerySetActionQueriesResponse & resp);
-    bool onWUQuerysetActionAliases(IEspContext &context, IEspWUQuerySetActionAliasesRequest & req, IEspWUQuerySetActionAliasesResponse & resp);
+    bool onWUQuerysetQueryAction(IEspContext &context, IEspWUQuerySetQueryActionRequest & req, IEspWUQuerySetQueryActionResponse & resp);
+    bool onWUQuerysetAliasAction(IEspContext &context, IEspWUQuerySetAliasActionRequest &req, IEspWUQuerySetAliasActionResponse &resp);
     bool onWUCopyLogicalFiles(IEspContext &context, IEspWUCopyLogicalFilesRequest &req, IEspWUCopyLogicalFilesResponse &resp);
 
     bool onWUInfo(IEspContext &context, IEspWUInfoRequest &req, IEspWUInfoResponse &resp);

+ 4 - 0
esp/smc/SMCLib/exception_util.hpp

@@ -114,6 +114,10 @@
 #define ECLWATCH_PSEXEC_NOT_INSTALLED           ECLWATCH_ERROR_START+94
 #define ECLWATCH_NO_WUID_SPECIFIED          ECLWATCH_ERROR_START+95
 
+#define ECLWATCH_QUERYSET_NOT_FOUND         ECLWATCH_ERROR_START+96
+#define ECLWATCH_QUERYID_NOT_FOUND          ECLWATCH_ERROR_START+97
+#define ECLWATCH_ALIAS_NOT_FOUND            ECLWATCH_ERROR_START+98
+
 inline void FORWARDEXCEPTION(IEspContext &context, IException *e, unsigned codeNew)
 {
     if (!e)