OEJMX - Chained Queries

Posted by ssouthwe on 15-Apr-2020 22:26

OE12.0, PASOE

The documentation around how oejmx works seems to show some simple examples, but doesn't go into detail on syntax.  In some cases, there's a disconnect between what the docs say, and how it actually behaves.

My question relates to .qry files with multiple query lines.

The documents and examples hint at a few things:

  • Queries can have multiple lines in them (see default.qry that ships with the product)
  • Queries have substitution tokens such as AGENT_ID.  I can't tell whether this is just some typographic convention for documentation, or whether you can have a parameterized query.  It seems absurd to make a user write a new query just to add an agent_id to it.
  • Data from one query's output can be used in another query.

Testing this out, I created a query: (I'd like to use RefreshAgents, but it doesn't exist in v12)

{"O":"PASOE:type=OEManager,name=AgentManager","M":["getAgents","oePasABL"]}
{"O":"PASOE:type=OEManager,name=AgentManager","M":["stopAgent","AGENT_ID",10,10]}

What I thought might happen is that the output from the first line would feed into the second line, replacing AGENT_ID.

What actually happened was that it ignored the App name I gave it "oePasABL" and instead ran stopAgent against every single app I had on the instance, and every agent under each app.  Here's the output:

Query: Line 1. Object: PASOE:type=OEManager,name=AgentManager, Method: getAgents(oePasABL)
Result: {"getAgents":{"agents":""}}
#====================================
Query: Line 0. Object: PASOE:type=OEManager,name=OeablServiceManager, Attribute: Applications
Result: {"Applications":[{"OEType":"APPLICATION","webapps":[snip]}
#====================================
Query: Line 0. Object: PASOE:type=OEManager,name=AgentManager, Method: getAgents(CreateABL)
Result: {"getAgents":{"agents":[{"agentId":"-rsNQkuiR2KydGbPvCGx0w","pid":"23874","state":"AVAILABLE"}]}}
#====================================
Query: Line 0. Object: PASOE:type=OEManager,name=AgentManager, Method: getAgents(oePasABL)
Result: {"getAgents":{"agents":""}}
Result: Error!: Not valid agent info
#====================================
Query: Line 0. Object: PASOE:type=OEManager,name=AgentManager, Method: getAgents(anotherpas)
Result: {"getAgents":{"agents":[{"agentId":"R5rxI0NkQXaJquiIQtzd6w","pid":"23846","state":"AVAILABLE"}]}}
#====================================
Query: Line 2. Object: PASOE:type=OEManager,name=AgentManager, Method: stopAgent(-rsNQkuiR2KydGbPvCGx0w, 10, 10)
Result: {"stopAgent":true}
#------------------------------------
Query: Line 2. Object: PASOE:type=OEManager,name=AgentManager, Method: stopAgent(R5rxI0NkQXaJquiIQtzd6w, 10, 10)
Result: {"stopAgent":true}

What's the syntax (if any) to get one query to feed into another?

If this isn't possible, what's the best way in V12 to kill off all the agents for a given ABL app?  Restarting the instance is not a viable option for production, nor is OEManager or anything that isn't scriptable.

I'd really rather have a very simple command-line that I can run, instead of having to try to write some code or install a component that the docs say is not for production.

Thanks.

All Replies

Posted by Irfan on 16-Apr-2020 13:45

Hi Steve,

Every query is different and having them in a file just runs the bunch of queries and dumps them to the same output. As you have noticed we have different tokens APP_NAME,AGENT_ID,SESSION_ID which are tokens that will be picked-up while running the queries dynamically. Currently the oejmx ability is to run only one given query, but not to execute a bunch of queries which parses the output from one query to another.

As they are just commands with parsable JSON as output, one can easily write a script based on platform to run multiple queries.

For your question, if you want to terminate agent then you would run this query(if stored in stopAgent.qry)

{"O":"PASOE:type=OEManager,name=AgentManager","M":["stopAgent","AGENT_ID",0,0]}

So to execute that I would do something like this

./oejmx.sh -R -Q stopAgent.qry -O

There is also a command to terminate all the sessions of an agent for the given ABLApp. Its basically like restarting the PASOE server as there are no sessions in the agent available(until unless you have to change the database or changes in the spring layer).

./tcman.sh jmx refreshagents -appname <ABLAppName>

If the ABLAppName is "oepas1" then it would be

./tcman.sh jmx refreshagents -appname oepas1

Posted by ssouthwe on 16-Apr-2020 18:33

[quote user="Irfan"]

For your question, if you want to terminate agent then you would run this query(if stored in stopAgent.qry)

{"O":"PASOE:type=OEManager,name=AgentManager","M":["stopAgent","AGENT_ID",0,0]}

So to execute that I would do something like this

./oejmx.sh -R -Q stopAgent.qry -O

[/quote]Hi Irfan.  Thanks for the answer.  I'm still confused over your token "AGENT_ID" in the query you show above.  When you show the command to execute it, you don't show how AGENT_ID gets replaced.  I know I can hard-code it in the file, but how would you run the query to substitute that on the fly?

Regarding refreshagents - That doesn't exist in my 12.0 install.  I wish it did, then i'd be done right now.

Posted by Irfan on 16-Apr-2020 19:07

HI Steve,

You wouldn't replace it on the fly. You have to create a query file with the token "AGENT_ID" in it and you can use that query file.

I think refreshagents JMX command was added in 12.1. So if you are using just 12.0 then you will not see it.

Posted by ssouthwe on 16-Apr-2020 19:17

When you say the word "token" I take that to mean that *something* replaces that with the actual agent id.  That's what I'm trying to get at.

Do you literally want the user to edit the file and put the real agent id value in it, or do you leave "AGENT_ID" exactly like that in the file?  If the latter, then how does it know which one to use?

Posted by Irfan on 16-Apr-2020 20:32

What I meant was to create a query file like

{"O":"PASOE:type=OEManager,name=AgentManager","M":["stopAgent","AGENT_ID",0,0]}

If you define "AGENT_ID" in the query then it should iterate over all the agents that are defined per that ABLApp and stop all of them. Similarly when you use the token SESSION_ID and APP_NAME.

If you specifically want to do it for one agent, then you have to replace the actual agentId in the query file. I have an example of how I do it from a script if you want. I have it working for both linux and windo[View:/cfs-file/__key/communityserver-discussions-components-files/19/oejmx_5F00_tricks.zip:320:240]ws.

Posted by ssouthwe on 16-Apr-2020 20:36

How would it know what ABLApp to use?

Posted by ssouthwe on 16-Apr-2020 21:22

For what it's worth, I had to build a shell script to get this done.  It's dirty as heck, but it works:

stopagents.sh

#/bin/sh
#######################################
# Query for running agents using oejmx.
# Stop those agents
# by S.E. Southwell
#######################################
# Customize these
CATALINA_HOME=/apps/applications/pasoe/dev
APP_NAME=$1

TEMP=$CATALINA_HOME/temp

if [ "$1" == "" ]; then
  echo "No ABL appname was provided.  Usage: restartagents.sh ABLappname"

else

  cd $TEMP
  echo \{\"O\":\"PASOE:type=OEManager,name=AgentManager\",\"M\":[\"getAgents\",\"$1\"]\} > ./${APP_NAME}agents.qry
  $CATALINA_HOME/bin/oejmx.sh -Q ./${APP_NAME}agents.qry -R -O ./agentslist.json
  cat ./agentslist.json | sed 's/^.*agentId/\nagentId/g' | sed 's/,.pid.*$//g' | sed 's/"//g' | grep agentId | sed 's/agentId://g' > agentslist.txt
  while read line
  do
    echo \{\"O\":\"PASOE:type=OEManager,name=AgentManager\",\"M\":[\"stopAgent\",\"$line\",10,10]\} > ./${APP_NAME}stopagent.qry
    $CATALINA_HOME/bin/oejmx.sh -Q ./${APP_NAME}stopagent.qry -R -O ./stoplist.json
    cat ./stoplist.json
  done < agentslist.txt
fi

This thread is closed