Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Modify Staf result

Help
shoyab
2012-12-28
2013-06-12
  • shoyab
    shoyab
    2012-12-28

    Hello, I am new to staf and I had a question that when I run:

    staf local process start shell command "route -n" returnSTDOUT WAIT

    my result is:

    Response

    {
      Return Code: 0
      Key        : <None>
      Files      : [
        {
          Return Code: 0
          Data       : Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         192.168.10.1    0.0.0.0         UG    0      0        0 em1
    192.168.10.0    0.0.0.0         255.255.255.0   U     0      0        0 em1

        }
      ]
    }

    and my requirement is I need to capture only Data part i.e.,

    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         192.168.10.1    0.0.0.0         UG    0      0        0 em1
    192.168.10.0    0.0.0.0         255.255.255.0   U     0      0        0 em1

    maybe it is from STAF PROCESS COMMAND or STAX MONITOR LOGS


    Thanks

     
  • Sharon Lucas
    Sharon Lucas
    2012-12-30

    If you submit this STAF service request via a program using a STAF API for Java, C/C++, Python, Perl, or Tcl (instead of using the STAF command line executable), then you can access the File's Data field in the result directly.  For examples, see the following documents accessible via the STAF Documentation web page at http://staf.sourceforge.net/docs.php:

    - STAF Java User's Guide (HTML) - This document describes STAF's V3 support for the Java language. It includes information on the core STAF Java APIs as well as the wrappers provided for the Monitor and Log services.
    - Sections "6.2 C" and  "6.3 C++" in the STAF V3 User's Guide documents STAF's support for C/C++.
    - STAF Python User's Guide (HTML) - This document describes STAF's V3 support for the Python language. It includes information on the core STAF Python APIs.
    - STAF Perl User's Guide (HTML) - This document describes STAF's V3 support for the Perl language. It includes information on the core STAF Perl APIs.
    STAF Tcl User's Guide (HTML) - This document describes STAF's V3 support for the Tcl language. It includes information on the core STAF Tcl APIs.

     
  • shoyab
    shoyab
    2012-12-31

    Hello slucas, Thanks for your reply and can't I submit STAF request from a linux shell script. Can I use the Python's STAF API for shell script

     
  • Sharon Lucas
    Sharon Lucas
    2013-01-02

    You can use STAF's Python APIs via a Python script.  You could run the Python script via a shell script if you wanted.

     
  • shoyab
    shoyab
    2013-01-02

    Thanks for your info

     
  • shoyab
    shoyab
    2013-01-02

    Hello slucas

    This is my C++ code to unmarshall the STAFResult:

    #include<iostream>
    #include "/usr/local/staf/include/STAF.h"
    #include "/usr/local/staf/include/STAF_iostream.h"

    using namespace std;

    int main()
    {
    STAFHandlePtr handle;
    unsigned int rc  = STAFHandle::create("MyApplication", handle);

    if (rc != 0)
    {
            cout << "Error registering with STAF, RC: " << rc << endl;
            return rc;
    }
    cout << "Successfully registered with STAF" << endl;

    STAFString machine = STAFString("local");

    STAFResultPtr result = handle -> submit(machine, "process", "start shell command route -n returnSTDOUT WAIT");
    if(result->rc != 0)
    {
            cout << "Process request failed with RC= " << STAFString(result->rc) << "Result= " << result->result << endl;
            return result->rc;
    }
    cout << "Result= " << result->result << endl;

    STAFObjectPtr mc = STAFObject::unmarshall(result->result);

    cout << "Process result (Pretty Printed): " << endl << mc->asFormattedString() << endl << endl;

    STAFObjectPtr queueEntryMap = mc->getRootObject();

    STAFString message = queueEntryMap->get("message")->asString();

    cout << "Message: " << message << endl;

    return 0;
    }

    And my output is :

    Successfully registered with STAF

    Marshalled Result:

    Result= @SDT/*:1008:@SDT/{:587::13:map-class-map@SDT/{:559::35:STAF/Service/Process/CompletionInfo@SDT/{:261::4:keys@SDT/[3:189:@SDT/{:56::12:display-name@SDT/$S:11:Return Code:3:key@SDT/$S:2:rc@SDT/{:48::12:display-name@SDT/$S:3:Key:3:key@SDT/$S:3:key@SDT/{:55::12:display-name@SDT/$S:5:Files:3:key@SDT/$S:8:fileList:4:name@SDT/$S:35:STAF/Service/Process/CompletionInfo:35:STAF/Service/Process/ReturnFileInfo@SDT/{:198::4:keys@SDT/[2:126:@SDT/{:56::12:display-name@SDT/$S:11:Return Code:3:key@SDT/$S:2:rc@SDT/{:50::12:display-name@SDT/$S:4:Data:3:key@SDT/$S:4:data:4:name@SDT/$S:35:STAF/Service/Process/ReturnFileInfo@SDT/%:399::35:STAF/Service/Process/CompletionInfo@SDT/$S:1:0@SDT/$0:0:@SDT/[1:327:@SDT/%:316::35:STAF/Service/Process/ReturnFileInfo@SDT/$S:1:0@SDT/$S:254:Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         192.168.10.1    0.0.0.0         UG    0      0        0 em1
    192.168.10.0    0.0.0.0         255.255.255.0   U     0      0        0 em1

    Unmarshalled Result:

    Process result (Pretty Printed):
    {
      Return Code: 0
      Key        : <None>
      Files      : [
        {
          Return Code: 0
          Data       : Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         192.168.10.1    0.0.0.0         UG    0      0        0 em1
    192.168.10.0    0.0.0.0         255.255.255.0   U     0      0        0 em1

        }
      ]
    }

    Message: <None>

    But I need only the data part i.e.,

    Data       : Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         192.168.10.1    0.0.0.0         UG    0      0        0 em1
    192.168.10.0    0.0.0.0         255.255.255.0   U     0      0        0 em1

    if there is any solution for this it helps me alot


    Thanks

     
  • Sharon Lucas
    Sharon Lucas
    2013-01-02

    You are almost there.  What you are doing wrong is that you are trying to access a field named "message" from the root object (a map) of the result and there is no field named "message" in this map.  The field you want to access is named "fileList".  For a description of the fields in the map result object from a sucessful PROCESS START WAIT request, see section "8.13.2 START", sub-section "Results" in the STAF User's Guide at http://staf.sourceforge.net/current/STAFUG.htm#HDRPROCSRV.  It says:

    "If the WAIT option is specified and the submit call does not timeout, the result buffer will contain a marshalled <Map:STAF/Service/Process/CompletionInfo> which represents the completion information for the process, including the return code from the process, the KEY (if one was specified with the NOTIFY ONEND option), as well as any files specified by RETURNSTDOUT, RETURNSTDERR, and/or RETURNFILE."

    And see tables 61 and 62 in this section for a definition of map class STAF/Service/Process/CompletionInfo and map class STAF/Service/Process/ReturnFileInfo.

    So, here's an updated version of your C++ program that outputs just the process's stdout "Data" value:

    #include<iostream>
    #include "/usr/local/staf/include/STAF.h"
    #include "/usr/local/staf/include/STAF_iostream.h"
    using namespace std;
    int main()
    {
        STAFHandlePtr handle;
        unsigned int rc  = STAFHandle::create("MyApplication", handle);
        if (rc != 0)
        {
            cout << "Error registering with STAF, RC: " << rc << endl;
            return rc;
        }
        cout << "Successfully registered with STAF" << endl;
        STAFString machine = STAFString("local");
        STAFString command = STAFString("route -n");
        STAFString request = STAFString("START SHELL COMMAND ") +
            handle->wrapData(command) + "RETURNSTDOUT STDERRTOSTDOUT WAIT";
        STAFResultPtr result = handle -> submit(machine, "PROCESS", request);
        if (result->rc != 0)
        {
            cout << "Process request failed with RC= "
                 << STAFString(result->rc) << "Result= " << result->result << endl;
            return result->rc;
        }
        // Note: You do not have to unmarshall the result yourself as this is done
        // automatically for you.  You can access the marshalling context from
        // result->resultContext and the root object of the unmarshalled result
        // from result->resultObj
        //   STAFObjectPtr mc = STAFObject::unmarshall(result->result);
        //   STAFObjectPtr queueEntryMap = mc->getRootObject();
        cout << "Process result (Pretty Printed): "
             << endl << result->resultContext->asFormattedString() << endl << endl;
        STAFObjectPtr processMap = result->resultObj;
        STAFString processRC = processMap->get("rc")->asString();
        STAFObjectPtr fileList = processMap->get("fileList");
        STAFObjectIteratorPtr fileListIter = processMap->get("fileList")->iterate();
        STAFObjectPtr stdoutMap = fileListIter->next();
        STAFString stdoutRC = stdoutMap->get("rc")->asString();
        STAFString stdoutData = stdoutMap->get("data")->asString();
        if (processRC == "0")
        {
            if (stdoutRC == "0")
            {
                cout << "Process Stdout Data: " << endl << stdoutData
                     << endl << endl;
            }
            else
            {
                cout << "Error retrieving process stdout.  stdoutRC=" << stdoutRC
                     << ", stdoutData=" << stdoutData << endl;
            }
        }
        else
        {
            cout << "Process did not return rc 0.  Process RC: " << processRC
                 << endl << "Stderr Data: " << stdoutData << endl << endl;
        }
        return 0;
    }
    
     
  • shoyab
    shoyab
    2013-01-03

    Thank you very much slucas