Automic Workload Automation

Expand all | Collapse all

Set agent group of a job programmatically

  • 1.  Set agent group of a job programmatically

    Posted 02-09-2016 06:28 PM

    The following JOBI, UC4.RESOLVE_AGENT_GROUP.JOBI, allows one to set an agent group programmatically/dynamically.

     

    See the updated version of this JOBI in the comment below.
    To use the JOBI, just include a few lines in the process tab of the parent workflow of the jobs that will use this agent group:
    :SET &AGENT_OR_AGENTGROUP# = "WINFT"
    :INCLUDE UC4.RESOLVE_AGENT_GROUP.JOBI
    :SET &ACTUAL_TARGET_AGENT# = &AGENT#

    This JOBI acts like a function:

    •  Input: &AGENT_OR_AGENTGROUP# — the name of anagent or an agent group.
    • Output: &AGENT# —
      • If &AGENT_OR_AGENTGROUP# contains the name of anagent, then this agent name (if it is active);
      • If &AGENT_OR_AGENTGROUP# contains the name of anagent group, then the next active agent in that agent group.
    Then simply insert :PUT_ATT HOST = &ACTUAL_TARGET_AGENT# into the pre-process of any job that should run on the agent or agent group. (If the job is a file transfer job, put the attribute FT_SRC_HOST or FT_DST_HOST instead.) And again, this approach works whether &AGENT_OR_AGENTGROUP# is set to the name of an agent or an agent group.  

    Update: for an updated version, see this comment, below.

    For an alternative, check out the clever approach by 
    joel_wiesmann_automic that uses nested workflows and a VARA object reference.


  • 2.  Set agent group of a job programmatically

    Posted 02-10-2016 05:17 AM
    Hi Michael, interesting approach. This is a nice solution in case that agentgroups are used for desaster-recovery / offline-agent-switch agentgroups. Guess I'll integrate it with my code (as you did all the work already :)). For jobs that must run always on all systems the {}-solution might still be prefered.


  • 3.  Set agent group of a job programmatically

    Posted 02-14-2018 08:35 AM

    I’ve encountered another quirk in the behavior of PREP_PROCESS_AGENTGROUP when the agent group has no active agents:

    • Sometimes, the function creates a data sequence with an agent name and 'N' for the status.
    • Other times, the function creates an empty data sequence (zero lines).

    Has anyone seen this before? (v12.1.1)



  • 4.  Set agent group of a job programmatically

    Posted 02-15-2018 11:52 AM

    I developed an improved version of the JOBI that gracefully handles the aforementioned problem with PREP_PROCESS_AGENTGROUP.

    It also skips to the post-process if no active agent can be found. I made this change so that I could use this JOBI in the set of general-purpose EXEC VARAs I’m developing.

    :PRINT "--- BEGIN UC4.RESOLVE_AGENT_GROUP.JOBI ---"
    :ON_ERROR RESUME
    :SET &AG_AGENT# = ""
    :SET &PreProc_Error# = "No error"
    :SET &Run_PostProc_on_Error# = &Run_PostProc_on_Error#
    :SET &Stop_on_Error# = &Stop_on_Error#
    :SET &Stop_Message_Num# = &Stop_Message_Num#
    :IF &Stop_Message_Num# = ""
    :  SET &Stop_Message_Num# = "0"
    :ENDIF
    :IF &AGENT_OR_AGENTGROUP# <> ""
    :  SWITCH GET_OBJECT_TYPE(&AGENT_OR_AGENTGROUP#)
    :  CASE 'HOSTG'
    :    PRINT "&AGENT_OR_AGENTGROUP# is an agent group. Resolving it..."
    :    SET &AG_HND# = PREP_PROCESS_AGENTGROUP(&AGENT_OR_AGENTGROUP#,,'BY_RULE')
    :    PROCESS &AG_HND#
    :      SET &AG_AGENT# = GET_PROCESS_LINE(&AG_HND#,1)
    :      SET &AGENT_UP# = GET_PROCESS_LINE(&AG_HND#,2)
    :      PRINT "Agent chosen by rule from agent group: &AG_AGENT#"
    :      IF &AGENT_UP# = 'Y'
    :        PRINT "Agent is up."
    :        SET &AGENT# = &AG_AGENT#
    :        TERM_PROCESS
    :      ELSE
    :        SET &Message# = "No active &AGENT_OR_AGENTGROUP# agent!"
    :        PRINT "ERROR: &Message#"
    :        SET &PreProc_Error# = "No active agent in agent group (1)"
    :      ENDIF
    :    ENDPROCESS
    :    CLOSE_PROCESS &AG_HND#
    !    Sometimes, PREP_PROCESS_AGENTGROUP returns an empty data sequence.
    :    IF &AG_AGENT# = " "
    :      SET &Message# = "No active &AGENT_OR_AGENTGROUP# agent!"
    :      PRINT "ERROR: &Message#"
    :      SET &PreProc_Error# = "No active agent in agent group (2)"
    :    ENDIF
    :  CASE 'HOST'
    :    PRINT "&AGENT_OR_AGENTGROUP# is an agent."
    :    SET &AGENT_UP# = SYS_HOST_ALIVE(&AGENT_OR_AGENTGROUP#)
    :    IF &AGENT_UP#  = "Y"
    :      PRINT "Agent is up."
    :      SET &AGENT# = &AGENT_OR_AGENTGROUP#
    :    ELSE
    :      SET &Message# = "Agent &AGENT_OR_AGENTGROUP# is down!"
    :      PRINT "ERROR: &Message#"
    :      SET &PreProc_Error# = "Agent is down."
    :    ENDIF
    :  OTHER
    :    PRINT "&AGENT_OR_AGENTGROUP# is not a known agent or agent group."
    :    SET &Message# = "&AGENT_OR_AGENTGROUP# unknown!"
    :    PRINT "ERROR: &Message#"
    :    SET &PreProc_Error# = "Unknonwn agent/agent group"
    :  ENDSWITCH
    :ELSE
    :  PRINT "No agent or agent group specified in variable &&AGENT_OR_AGENTGROUP#."
    :ENDIF

    ! Check for agent/job type mismatch
    :IF &AGENT# <> ""
    :  PRINT "Object name    : &$NAME#"
    :  PRINT "Object type    : &$OBJECT_TYPE#"
    :  SET &OBJ_SUBTYPE# = GET_VAR(UC4.GET_OBJ_SUBTYPE.VARA_SEC_SQLI)
    :  PRINT "Object subtype : &OBJ_SUBTYPE#"
    :  SET &AGENT_TYPE# = GET_VAR(UC_HOST_JCL_VAR,&AGENT#)
    :  PRINT "Agent name     : &AGENT#"
    :  PRINT "Agent type     : &AGENT_TYPE#"
    :  IF &OBJ_SUBTYPE# <> &AGENT_TYPE#
    :    PRINT "Mismatch between job subtype and agent type."
    :    SET &Message# = "Cannot switch to agent of different type!"
    :    PRINT "ERROR: &Message#"
    :    SET &PreProc_Error# = "Job/agent type mismatch"
    :  ENDIF
    :ENDIF
    :RSET &PreProc_Error# = &PreProc_Error#

    ! Begin error handling
    :IF &PreProc_Error# <> "No error"
    :  PRINT "Error encountered in pre-process."
    :  IF &Run_PostProc_on_Error# = "YES"
    :    PRINT "&&Run_PostProc_on_Error# = 'YES'. Running post-process."
    :    INC_SCRIPT(2)
    :  ENDIF
    :  IF &Stop_on_Error# = "YES"
    :    PRINT "&&Stop_on_Error# = 'YES'. Stopping task with message number &Stop_Message_Num#."
    :    STOP NOMSG,&Stop_Message_Num#
    :  ENDIF
    :ENDIF
    :PRINT "--- END UC4.RESOLVE_AGENT_GROUP.JOBI ---"

    More to come...

    Update 2018.02.16 12:30 CET: I added handling for a non-existent agent/agent group.
    Update 2018.02.16 20:10 CET: I added handling for a mismatch between the type of the job and the agent.



  • 5.  Set agent group of a job programmatically

    Posted 02-16-2018 04:40 AM
    Interesting use of INC_SCRIPT. Does that throw FAULT_OTHER from time to time? Like when using MODIFY_STATE as it will be executed as part of prescript?


  • 6.  Set agent group of a job programmatically

    Posted 02-16-2018 06:26 AM
    joel_wiesmann_automic: At least for the situations I have encountered so far, the :STOP NOMSG statement allows the job to avoid FAULT_OTHER. The task ends with the status ENDED_EMPTY - task is empty (STOP NOMSG).


  • 7.  Set agent group of a job programmatically

    Posted 02-16-2018 08:43 AM
    I am still improving it to make it more versatile. E.g., here is a message that is not currently handled:
    U00020558 Runtime error in object 'UC4.GP_SQL.JOBS(1)' line '00018': Change of platform not allowed ('<SQL>/SQL' to 'JUPITER1/UNIX' refused)



  • 8.  Set agent group of a job programmatically

    Posted 02-16-2018 02:16 PM
    I updated the JOBI with another check to avoid triggering U00020558. This required creating a new SEC_SQLI VARA to look up the job subtype. (There really should be a predefined object variable for this, e.g., &$OBJECT_SUBTYPE#.)


  • 9.  Set agent group of a job programmatically

    Posted 02-22-2018 04:13 PM
    I copied this JOBI and instructions for its use to my Github repository.


  • 10.  Re: Set agent group of a job programmatically

    Posted 07-09-2018 11:22 PM

    Hi Michael,

    Thank you for the script.

    I am also have the problem while using the GET_FILESYSTEM with the HOSTG. The GET_FILESYSTEM function supports only HOST, then I need to find the way to get the active agent from HOSTG. Finally I'm using the GET_ATT(HOSTG) and it returns the active agent for me.

    Does the GET_ATT(HOSTG) is different from the script above?



  • 11.  Re: Set agent group of a job programmatically

    Posted 07-10-2018 02:47 AM

    Although its primary purpose is to look up an agent from an agent group, my script does do more than that. Read it to learn more.



  • 12.  Re: Set agent group of a job programmatically

    Posted 08-14-2018 11:54 AM

    I updated the JOBI again. The new JOBI is on my GitHub repo. Changes:

    • Check agent group existence
    • Check agent group mode. This isn't really used for much at the moment, other than to print a warning that only one agent will be selected for agent groups of mode all. This change adds a dependency on a new SEC_SQLI.