PAS - Pick up new r-code

Posted by dbeavon on 13-Dec-2017 07:43

I've been using PAS for some time and have often made use of the "resource timeout" to kill my _mproapsv.exe after a specified number of seconds so that it will pick up new r-code.

In prior posts (by Irfan and David Cleary?) I had heard some hints of a feature whereby the jconsole (via JMX) would allow us to manage PAS agents and clear out the cached r-code.  However, I'm not finding anything that appears to be a direct match for that feature.  Below is the list of API methods.

As best I can tell, the only way to clear out the cached r-code is to run stopAgent on it.  Is that the recommended approach?

Posted by Irfan on 13-Dec-2017 08:48

I just tried to create a class file with a property to get the value on the property 'test1' and deployed it in PASOE PROPATH.

CLASS OpenEdge.Test.TestSingleton: 
    
    
    define public static property test1 as int init 1
        get.    
    
        set.    
    
  END CLASS.




Make multiple calls over a APSV to that class from a procedure and it worked fine. Changed the property INIT to a different value and then executed
'terminateFreeABLSessions' API , observed that the sessions got terminated and then on a new request I see that the changed property INIT value is reflected correctly.

So I think 'terminateFreeABLSessions' would be a better API to refresh the rcode.

All Replies

Posted by dbeavon on 13-Dec-2017 07:52

Here is the David Cleary quote.  After reading this again, I see that he said it was necessary to "bounce the (MS-) agent process".  


We also have an API to bounce the agent process without taking down the server. This will allow you to reset any static or singleton r-code a session may have loaded. You need oemanager installed to access this through REST, or use JMX.

https://community.progress.com/community_groups/openedge_general/f/26/p/21847/81335?pi20882=1

I guess that answers my question.  I suspect there is not a more efficient way to pick up new r-code than that. 

I'm assuming that r-code is shared by the whole MS-agent and not specific to the individual ABL sessions within the agent; so it probably wouldn't help to terminate and restart individual ABL sessions, right?

Thanks for any clarification about r-code management in PAS.

Posted by jankeir on 13-Dec-2017 08:05

Don't know about doing it through JMS, but I clear the .r file cache in activate.p when appropriate (I can detect the release of new .r files in a db record) using the following statement:

CURRENT-LANGUAGE       = CURRENT-LANGUAGE.

Because the current-language changes and .r code can be translated, this will clear the cache. Mind that persistent procedures and classes are still loaded, so you may want to possibly cache their state, kill them, and reload them after the current-language change, so depending on how your code works, it may not be as simple as you'd hope.

Posted by jankeir on 13-Dec-2017 08:07

Mind that I have not tested this on PASOE, only on classic appserver.

Posted by Irfan on 13-Dec-2017 08:48

I just tried to create a class file with a property to get the value on the property 'test1' and deployed it in PASOE PROPATH.

CLASS OpenEdge.Test.TestSingleton: 
    
    
    define public static property test1 as int init 1
        get.    
    
        set.    
    
  END CLASS.




Make multiple calls over a APSV to that class from a procedure and it worked fine. Changed the property INIT to a different value and then executed
'terminateFreeABLSessions' API , observed that the sessions got terminated and then on a new request I see that the changed property INIT value is reflected correctly.

So I think 'terminateFreeABLSessions' would be a better API to refresh the rcode.

Posted by dbeavon on 13-Dec-2017 09:47

Thanks for the tip Irfan.  Sounds like the MS-agent process is able to replace its code after all.  That is good to know.  Can you point me to a REST equivalent? (link: https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/pasoe-admin%2Fget-session-information.html%23 )

I typically use the "-q" option on my ABL sessions which may be inflexible about detecting changes in r-code.  So I went ahead and wrote a powershell

script for that case:

$agent= $null
$response = $null
$response2 = $null

# Store credentials
$pass="tomcat" | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object   System.Management.Automation.PsCredential('tomcat',$pass)

# Retrieve available agents
$response = Invoke-RestMethod -Uri hhhp:/xyz.com:8815/oemanager/applications/abl_application/agents -Credential $cred 

# Parse out the results into JSON
$jsonstring = ConvertTo-Json -InputObject $response -Depth 3
$json = ConvertFrom-Json -InputObject $jsonstring 

# Retrieve an available agent 
$agent = $json.result.agents | Where-Object -Property 'state' -EQ 'AVAILABLE' 
 
# delete the agent 
$response2 = Invoke-RestMethod -Method Delete -Uri ('hhhp:/xyz.com:8815/oemanager/applications/abl_application/agents/' + $agent.agentId) -Credential $cred  -ContentType "application/vnd.progress+json"

# Display summary
Write-Output "Delete operation was sent to oemanager REST URI"
Write-Output ("Deleted ID : " + $agent.agentId + " - " + $response2.outcome + " " +  $response2.result )
 

Hope this saves someone else a bit of time.

Posted by Peter Judge on 13-Dec-2017 09:52

Just note that that terminate operation kills the sessions (does not simply reload rcode).
 

Posted by dbeavon on 13-Dec-2017 10:03

Note that my powershell script wasn't written to use the "terminateFreeABLSessions" API that was suggested by Irfan so it probably runs slower than necessary (although it may work better for MS-Agents that are started with the -q parameter). I am still not certain that the API method "terminateFreeABLSessions" is available on the REST side of things.

Also please note that my powershell script is extremely simple and only operates on a single ABL application and assumes a single MS-Agent will be present (with state AVAILABLE).  These assumptions are based on my requirements in the development environment.

Finally, the version of powershell that I used was as follows.  I'm not sure if the features I used are available on other versions:

$PSVersionTable.PSVersion

Major  Minor  Build  Revision

-----  -----  -----  --------

5      1      15063  726    

Posted by Irfan on 13-Dec-2017 10:26

There is a REST API too, I am thinking of providing you a better approach to use this API. Will let you know.

Posted by Irfan on 13-Dec-2017 12:28

To terminate free ABL sessions, you have to do something like this.

curl -X DELETE -u tomcat:tomcat localhost:<http_port>/.../sessions

BTW, you are using powershell and writing your own code to call REST API's from the same host or a different host ?

Posted by dbeavon on 13-Dec-2017 14:15

Irfan,

Here is the link to the documentation for the REST URL that you are probably referring to: 

https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/pasoe-admin%2Fget-session-metrics.html%23

It allows the "Get" method to retrieve the list of sessions.  Below is an example (powershell running against localhost):

# Retrieve available agent sessions using abl app and agent id
$response = Invoke-RestMethod -Method Get -Uri ('hppp://localhost:8815/oemanager/applications/abl_app/agents/sK3ZTaBVRb-Ds9Qn9ZD9Ug/sessions') -Credential $cred 

However this does not support the HTTP "Delete" method directly.  The following fails with an error - 405 method not allowed:

# Delete agent sessions (-Method Delete)
$response = Invoke-RestMethod -Method Delete -Uri ('hppp://localhost:8815/oemanager/applications/abl_app/agents/sK3ZTaBVRb-Ds9Qn9ZD9Ug/sessions') -Credential $cred 

I believe the first HTTP request to get the sessions would need to be followed with another REST method which must be executed for every session:

https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/pasoe-admin%2Fterminate-a-session.html%23

Ideally it would be better if there were a way to directly call terminateFreeABLSessions via REST.

Posted by dbeavon on 13-Dec-2017 14:34

Based on investigating your JMX api in Jconsole and comparing to your REST api in oemanager, it seems that the PASOE team has invested quite a bit more of their time on the JMX side of things.  It also seems that there may be some redundant work going on in the oemanager webapp.

I am not a Java programmer by any stretch, but I was wondering if you have considered using Jolokia to wrap your JMX api and make it available via REST as well.  That way it would be more easily accessible and we wouldn't have to rely on duplicated efforts (both on the programming side of things and in your documentation).  

I was first aware of JMX when using the Jboss AMQ product which allows us to perform JMX management functions via REST url's.  Initially I had believed that JMX was inherently a REST-ful interface based on HTTP.  Now that I have seen JMX *without* Jolokia, it is clear that the REST portion is not always an integral component of JMX (but it probably should be).

Here are some Jolokia links.  As a powershell user it would help greatly if your JMX api was accessible via REST:

https://jolokia.org/

stackoverflow.com/.../connect-to-jmx-using-powershell

Posted by Irfan on 13-Dec-2017 15:23

My mistake, the URL should be something like this

curl localhost:<http_port>/.../sessions -u tomcat:tomcat -X DELETE -v -H 'Content-type: application/vnd.progress+json'

Notice that there is no 'agents' in the URL, we directly add the <agent-id.

Regarding your questions with JMX and REST,we always make sure that we have the same functionality for both JMX and REST API's. So you should be having access to API's which perform the same functionality using REST and JMX.

Posted by dbeavon on 13-Dec-2017 16:21

I couldn't find a way to directly call "terminateFreeABLSessions" via REST.   The approach you referenced does not appear to be the direct equivalent for terminating free ABL sessions.  I still think your JMX stuff appears to be more fully featured than the "oemanager" stuff.  Either way, there is definitely a lot of duplication going on in here... and the end results aren't exactly equivalent.  This forces a developer to have to learn the different syntax and API on both sides : JMX and REST.  It seems like it would be better to take the same approach as products like Jboss AMQ which uses Jolokia to make the JMX and REST more similar.

In your docs there seems to be a preference towards your JMX stuff over your REST stuff, especially when we need to be able to administer both development and production servers. See link: knowledgebase.progress.com/.../What-are-the-man-command-equivallents-for-OEPAS

Quote:

"The JMX interface is preferred compared to Manager / OE Manager war files shipped with OpenEdge for security reasons.

The REST API depends on the oemanager.war which should not be used in production, which is why the JMX interface should be preferred."

Posted by Irfan on 13-Dec-2017 19:22

Hi David,

I am not sure why you see different results in REST API.

This is what I did to get the agent-id




curl localhost:9810/.../agents -u tomcat:tomcat { "errmsg": "", "operation": "GET AGENTS", "outcome": "SUCCESS", "result": { "agents": [ { "agentId": "vehESXrsQTKWT2REvf9mjw", "pid": "29121", "state": "AVAILABLE" } ] }, "versionNo": 1, "versionStr": "v11.7.2 ( 2017-09-24 )" }

Then used the below API to terminatefreeABLSessions. Notice that the API does not have 'agents' in the URI

curl localhost:9810/.../sessions -u tomcat:tomcat -X DELETE -H 'Content-type: application/vnd.progress+json'


{
    "errmsg": "", 
    "operation": "TERMINATE SESSIONS", 
    "outcome": "SUCCESS", 
    "result": 2, 
    "versionNo": 1, 
    "versionStr": "v11.7.2 ( 2017-19-24 )"
}  

Now if I check the sessions in the agent, I should see the status as terminated.

 curl localhost:9810/.../sessions -u tomcat:tomcat -H 'Content-type: application/vnd.progress+json'

{
"versionStr": "v12.0.0 ( 2017-12-01 )",
"versionNo": 1,
"outcome": "SUCCESS",
"errmsg": "",
"operation": "",
"result": {
"AgentSession": [
{
"SessionId": 4,
"SessionState": "TERMINATED",
"StartTime": "2017-12-13T19:58:43.798",
"EndTime": "2017-12-13T20:09:26.457",
"ThreadId": -1,
"ConnectiondId": null,
 "SessionExternalState": 0,
 "SessionMemory": 230511
 },
 {
 "SessionId": 7,
 "SessionState": "TERMINATED",
 "StartTime": "2017-12-13T19:58:43.798",
 "EndTime": "2017-12-13T20:09:26.457",
 "ThreadId": -1,
 "ConnectiondId": null,
 "SessionExternalState": 0,
 "SessionMemory": 230512
 }
 ]
 }
}
 

You should see same results with JMX. The only thing that changes between JMX and REST is the way we call it, other than that the functionality and the response is same.

Posted by Irfan on 13-Dec-2017 20:23

David,

By default the REST API's for oemanager are not secure, which means any one who has access to the the PASOE Instance can access the REST API's if the password is not changed and the access is allowed to any user. One need to limit access of the REST API's if they want to keep it secure. OEM/OEE manage PASOE using REST API's. Anyone who uses their own UI console for administration chooses REST API's as you get the response in JSON.

JMX is secure and the reason is that it can only be accessed from the same host by default. To access it from the remote host, one need to enable jmx remote access. We have developed tools to run JMX queries securely. Please email me if you would like to learn more about it.

Posted by dbeavon on 26-Dec-2017 14:04


As far as I can tell, the REST URL that you gave me didn't have harmful side effects. I've never seen it terminate sessions that are "active" (which was my main fear - the REST URL itself doesn't seem to indicate one way or another if it will disconnect/terminate active sessions). REST API's aren't very self-descriptive and unfortunately they seem to require quite a lot of guess-work.  I haven't fully convinced myself that REST is better than SOAP.

For now I'll assume that this REST request does NOT impact active sessions and is SAFE for production (ie. if we swap out the r-code during a mid-day deployment to production, then we consider using this REST API as a mechanism for ensuring that the new code gets applied to all idle appserver sessions).  Here is the start of another powershell script:

param (
    [string]$ablapp = "abl_application",
    [Parameter(Mandatory=$true)][int]$portnumber
    
 )
  
  

$agent= $null
$response = $null
$response2 = $null
 
# Store credentials
$pass="tomcat" | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object   System.Management.Automation.PsCredential('tomcat',$pass)
 
# Retrieve available agents
$response = Invoke-RestMethod -Uri (hddp://localhost:' + $portnumber.ToString() + '/oemanager/applications/' + $ablapp + '/agents') -Credential $cred 
 
# Parse out the results into JSON
$jsonstring = ConvertTo-Json -InputObject $response -Depth 3
$json = ConvertFrom-Json -InputObject $jsonstring 
 
# Retrieve an available agent 
$agent = $json.result.agents | Where-Object -Property 'state' -EQ 'AVAILABLE' 
  
# Delete the agent sessions
$response2 = Invoke-RestMethod -Method Delete -Uri (hddp://localhost:' + $portnumber.ToString() + '/oemanager/applications/' + $ablapp + '/' + $agent.agentId + '/sessions') -Credential $cred # Display summary Write-Output "Delete sessions operation was sent to oemanager REST URI" Write-Output ("Deleted ID : " + $agent.agentId + " - " + $response2.outcome + " " + $response2.result )

 

As I noted earlier, this works pretty well for swapping out the r-code that was previously loaded by a session.  I was pleasantly surprised that even MS-agent processes started with "-q" will be able to receive refreshed code, without the need to restart the entire process.  It appears that r-code must be independently maintained for each session within the agent process.

Thanks for the help with this.

David

This thread is closed