SoftTree Technologies SoftTree Technologies
Technical Support Forums
RegisterSearchFAQMemberlistUsergroupsLog in
Calling a JAL script from Ruby

 
Reply to topic    SoftTree Technologies Forum Index » 24x7 Scheduler, Event Server, Automation Suite View previous topic
View next topic
Calling a JAL script from Ruby
Author Message
Brent



Joined: 20 Feb 2002
Posts: 57

Post Calling a JAL script from Ruby Reply with quote

Is it possible to call an external JAL script from a Ruby program, passing in a parameter and receiving back a return value?

If it is possible, what would the Ruby program need to do to call the script and receive the return value?

Thank you.

Thu Dec 09, 2004 10:12 am View user's profile Send private message
SysOp
Site Admin


Joined: 26 Nov 2006
Posts: 7969

Post Re: Calling a JAL script from Ruby Reply with quote

Sorry I've never heard of Ruby before and cannot say what you can do with it and what you cannot.

You can surely execute an external JAL script from batch jobs and other programs. There exist several methods for doing that but the most simple is to use a permanent JAL script job whose only script line is like below

@SCRIPT: C:\\Scripts\myscript.jal

This job will then run a dynamic script referenced in the @SCRIPT tag. To run this job from a batch file or other program run "24x7.EXE /JOB [this job number]"
Before you run it you can modify the referenced JAL file any way you want.
To return a value back, in the script use any available file, INI, registry, database, etc… methods to temporarily put the return value someplace from where you can then read it from your Ruby program after the JAL script terminates. If you need a simple numeric value as a return code you can call Windows API Proces#####it function (see Ca;; method description in the on-line docs) to kill the job process and return an exit code value to the parent process.

Similar things can be done using VBScript jobs in 24x7.

: Is it possible to call an external JAL script from a Ruby program, passing in
: a parameter and receiving back a return value?

: If it is possible, what would the Ruby program need to do to call the script
: and receive the return value?

: Thank you.

Thu Dec 09, 2004 11:15 am View user's profile Send private message
Brent



Joined: 20 Feb 2002
Posts: 57

Post Re: Calling a JAL script from Ruby Reply with quote

Here is my problem. We have a directory where files are being generated. When they are done being generated, they need to be processed. While the files are being generated, they are locked.

Ruby can watch the directory and process the files better than JAL, but JAL is the only language I have seen that can detect when these files are locked. Where would I find these methods you talk about to execute an external JAL script from another program?

: Sorry I've never heard of Ruby before and cannot say what you can do with it
: and what you cannot.

: You can surely execute an external JAL script from batch jobs and other
: programs. There exist several methods for doing that but the most simple
: is to use a permanent JAL script job whose only script line is like below

: @SCRIPT: C:\\Scripts\myscript.jal

: This job will then run a dynamic script referenced in the @SCRIPT tag. To run
: this job from a batch file or other program run "24x7.EXE /JOB [this
: job number]"
: Before you run it you can modify the referenced JAL file any way you want.
: To return a value back, in the script use any available file, INI, registry,
: database, etc… methods to temporarily put the return value someplace from
: where you can then read it from your Ruby program after the JAL script
: terminates. If you need a simple numeric value as a return code you can
: call Windows API Proces#####it function (see Ca;; method description in
: the on-line docs) to kill the job process and return an exit code value to
: the parent process.

: Similar things can be done using VBScript jobs in 24x7.

Thu Dec 09, 2004 11:51 am View user's profile Send private message
SysOp
Site Admin


Joined: 26 Nov 2006
Posts: 7969

Post Re: Calling a JAL script from Ruby Reply with quote

I see now what you want. You really want to execute individual JAL commands or little scripts from some other environment. You can do that only if that environment supports COM automation. You can do that, for example, from VBScript. In such case you can create instantiate 24x7 COM Remote Control object and use 24x7 API to run specific JAL commands as dynamic scripts. For more info see http://www.softtreetech.com/24x7/24x7_COM.pdf.

By the way, in 24x7 Scheduler you have several methods for monitoring directories:

1. File-watch schedule job can watch for multiple files using file mask and can also monitor their sizes until the processing is done. The job gets triggered only when all files are done. This is very simple and efficient.

2. JAL script type job using DirWaitForUpdate command setting a system hook for the monitored directory. Run this job on the schedule startup and set it to run asynchronous in the background running "forever". An example is available in the on-line help.

3. JAL script job running periodically and getting list of files, their sizes and dates and comparing all this to results of the previous run. If no changes found it assumes that files are done. This is not very complicated but will require several dozens lines of code.

In JAL you can also use FileOpen/FileClose commands with some error handling to check if files are locked.

4. In addition to all that you can check directory monitoring methods available in 24x7 Event Server http://www.softtreetech.com/24x7/24x7es_manual.pdf.

Tell me more what you can do in Ruby and cannot do in 24x7 and I will tell you how to do it in 24x7.

: Here is my problem. We have a directory where files are being generated. When
: they are done being generated, they need to be processed. While the files
: are being generated, they are locked.

: Ruby can watch the directory and process the files better than JAL, but JAL
: is the only language I have seen that can detect when these files are
: locked. Where would I find these methods you talk about to execute an
: external JAL script from another program?

Thu Dec 09, 2004 12:22 pm View user's profile Send private message
Brent



Joined: 20 Feb 2002
Posts: 57

Post Re: Calling a JAL script from Ruby Reply with quote

Here is what the program is doing:

1. The program runs forever.

2. The program checks a directory for a stop.txt file to cause the program to end (deleting the file before the program ends).

3. The program then calls a method over and over, given the directory to watch.

4. The method searches the given directory for a header file (always ends with _HDR.TXT). When found, the method searches for a matching detail file (always ends with _RPT.TXT). Example: Something_HDR.TXT will match up with Something_RPT.TXT. If the matching files are found, and the they are not locked, the program will merge the two files together and copy them to some destination, or copy them separately for backup purposes. If the merged file exists in the destination, the file is given a number in the name and copied (incrementing the number until a match is not found). The method also searches the directory for other files that end in a certain way for straight copying to some destination.

5. Upon a successful copy, the files in the given directory to the method are deleted.

Except for detecting the locked files, I have coded the program to watch one directory in only 122 lines of understandable code (blank lines and comments included in the count). This code includes a method to get the current directory, a method to change the current directory, a method to merge two files and send to the destination folder, a method to copy the other files that need to be copied, a method to process a given directory, and the main processing loop.

My dislike of JAL includes its complexity to do tasks. Some examples of tasks (coded in Ruby) are:

Dir["STOP.TXT"].each do |file|

In Ruby, this will perform a block of code if stop.txt exists in the directory.

if file1.gsub("_HDR.TXT","") == file2.gsub("_RPT.TXT","")

In Ruby, this one line will allow me to do processing if the first part of file1 matches the first part of file2.

while FileTest::exist?(destDir + File::Separator + currentPrint + destExt)

uniqueNumber += 1

destExt = "_#{uniqueNumber}_PRT.TXT"
end

In Ruby, these four lines will allow me to check the destination directory for the merged file, and increment the unique number in the file name until no match is found.

I have coded in JAL before, and I know that these tasks are far more complicated in JAL.

Thank you for your help. I will check out the PDFs you recommended.

: I see now what you want. You really want to execute individual JAL commands
: or little scripts from some other environment. You can do that only if
: that environment supports COM automation. You can do that, for example,
: from VBScript. In such case you can create instantiate 24x7 COM Remote
: Control object and use 24x7 API to run specific JAL commands as dynamic
: scripts. For more info see http://www.softtreetech.com/24x7/24x7_COM.pdf
: .

: By the way, in 24x7 Scheduler you have several methods for monitoring
: directories: 1. File-watch schedule job can watch for multiple files using
: file mask and can also monitor their sizes until the processing is done.
: The job gets triggered only when all files are done. This is very simple
: and efficient.

: 2. JAL script type job using DirWaitForUpdate command setting a system hook
: for the monitored directory. Run this job on the schedule startup and set
: it to run asynchronous in the background running "forever". An
: example is available in the on-line help.

: 3. JAL script job running periodically and getting list of files, their sizes
: and dates and comparing all this to results of the previous run. If no
: changes found it assumes that files are done. This is not very complicated
: but will require several dozens lines of code.

: In JAL you can also use FileOpen/FileClose commands with some error handling
: to check if files are locked.

: 4. In addition to all that you can check directory monitoring methods
: available in 24x7 Event Server
: http://www.softtreetech.com/24x7/24x7es_manual.pdf .

: Tell me more what you can do in Ruby and cannot do in 24x7 and I will tell
: you how to do it in 24x7.

Thu Dec 09, 2004 2:53 pm View user's profile Send private message
SysOp
Site Admin


Joined: 26 Nov 2006
Posts: 7969

Post Re: Calling a JAL script from Ruby Reply with quote

That sounds pretty simple. JAL is not a pretty language but it does the job. Here is how I would do it.

1 First of all create a new user defined method in the Script Library to check for file locked state. Let's call it IsFileLocked. This method would take one argument of string type for the file name and it will return boolean True/False indicating whether the file is locked or not. Example script:

/////////////////////////////////////////
OnErrorGoTo FILE_LOCKED
Dim( temp, number )
// Try to open file for reading (file_name is argument name)
FileOpen( file_name, "LineMode", "Read", "", file_number )
// If we are here we were able to open the file. Close it and return TRUE
FileClose( file_number )
Return( True )
FILE_LOCKED:
Return( False)
////////////////////////////////////////

2. Second I would create another method to check if the detail file is present and if yeas return file name, otherwise return an empty string. Let's call this method GetDetail, it will to have an argument for the header file name and it will return a string. This can be done as simple as the following:

/////////////////////////////////////////
Dim( len, number )
Dim(detail_name, string )
// header_name is an argument name. Let's calculate file name without _HDR.TXT suffix
Length( header_name, len )
Subtract( len, 8, len)
// Build detail file name
Left( header_name, len, header_name )
Concat( header_name, "_RPT.TXT", detail_name )
// Now, let's check if this file exists
Dim( file_found, boolean )
FileExists( detail_file, file_found )
If Then( file_find, GOT_IT)
Return( "" )
GOT_IT:
Return( detail_name )
////////////////////////////////////////

3. Third I would create another method to calculate the merge file name. Let's call this method GetReportName, it will have 2 arguments: detail file name and a target directory and it will return a string with the new file name. This could be done as simple as the following:
/////////////////////////////////////////
Dim( len, number )
Dim( suffix, number )
Dim( available, string )
Dim( new_name, string )
Dim( temp, string )

// replace source dir with target dir in the file name
SplitFileName( detail_name, temp, detail_name )
Concat( target_dir, detail_name, detail_name )

// Check if the name is available without suffix
Set( new_name, detail_name)
NotFileExists( new_name, available )
IfThen( available, DONE )

// Let's find an unique file number _RPT.TXT suffix ( If uniqueness is the only need and file name is not important, why not simply insert a timestamp suffix?)

Length( detail_name, len )
Subtract( len, 8, len)
Left( detail_name, len, detail_name )

// Now, let's roll
LoopWhile True, END_LOOP
Add( suffix, 1, suffix )
ConcatEx( detail_name, suffix, "_RPT.TXT", new_name )
NotFileExists( new_name, available )
IfThen( available, DONE )
END_LOOP:

DONE:
Return( new_name )
////////////////////////////////////////

3. Now here is the remaining part. Create job of script type, which will have a schedule [when certain files not found] and specify stop.txt file as the file to watch. In the job script code the following (all together it is less then 122 lines, including locking part and comemnts ):
////////////////////////////////////////////////////////////////////////////////////////
Dim( header_list, string )
Dim( header_file, string )
Dim( detail_file, string )
Dim( command, string )
Dim( is_empty, boolean )
Dim( file_lock, boolean)
Dim( pid, number )

// Get the list of all header files
DirEx( "c:\\whatever\\*_HDR.TXT", header_list )
// Loop through the list and check if detail is available and files are locked or not
IsEqual( header_list, "", is_empty )

LoopUntil( is_empty, END_LOOP )
// Get next header file
GetToken( ",", header_list, header_file )
// Check for detail (see step 2 above)
GetDetail( header_file, detail_file )
IsEqual( detail_file, "", is_empty )
IfThen( is_empty, TRY_NEXT_HEADER)

// Check for locks
IsFileLocked( header_file, file_lock)
IfThen( file_lock, TRY_NEXT_HEADER)
IsFileLocked( detail_file, file_lock)
IfThen( file_lock, TRY_NEXT_HEADER)

// Concat, copy and delete files
GetReportName( detail_file, "c:\\whatever is target\\", target_file )
ContactEx( "cmd /C copy \"", header_file, "\" + \"", detail_file, "\" \"", target_file, "\"", command)
RunAndWait( command, "", 0, pid )
FileDelete( header_file )
FileDelete( detail_file )

TRY_NEXT_HEADER
// check if there are more files in the list
IsEqual( header_list, "", is_empty )
END_LOOP:
////////////////////////////////////////////////////////////////////////////////////////

: Here is what the program is doing: 1. The program runs forever.

: 2. The program checks a directory for a stop.txt file to cause the program to
: end (deleting the file before the program ends).

: 3. The program then calls a method over and over, given the directory to
: watch.

: 4. The method searches the given directory for a header file (always ends
: with _HDR.TXT). When found, the method searches for a matching detail file
: (always ends with _RPT.TXT). Example: Something_HDR.TXT will match up with
: Something_RPT.TXT. If the matching files are found, and the they are not
: locked, the program will merge the two files together and copy them to
: some destination, or copy them separately for backup purposes. If the
: merged file exists in the destination, the file is given a number in the
: name and copied (incrementing the number until a match is not found). The
: method also searches the directory for other files that end in a certain
: way for straight copying to some destination.

: 5. Upon a successful copy, the files in the given directory to the method are
: deleted.

: Except for detecting the locked files, I have coded the program to watch one
: directory in only 122 lines of understandable code (blank lines and
: comments included in the count). This code includes a method to get the
: current directory, a method to change the current directory, a method to
: merge two files and send to the destination folder, a method to copy the
: other files that need to be copied, a method to process a given directory,
: and the main processing loop.

: My dislike of JAL includes its complexity to do tasks. Some examples of tasks
: (coded in Ruby) are: Dir["STOP.TXT"].each do |file|

: In Ruby, this will perform a block of code if stop.txt exists in the
: directory.

: if file1.gsub("_HDR.TXT","") ==
: file2.gsub("_RPT.TXT","")

: In Ruby, this one line will allow me to do processing if the first part of
: file1 matches the first part of file2.

: while FileTest::exist?(destDir + File::Separator + currentPrint + destExt)

: uniqueNumber += 1

: destExt = "_#{uniqueNumber}_PRT.TXT"
: end

: In Ruby, these four lines will allow me to check the destination directory
: for the merged file, and increment the unique number in the file name
: until no match is found.

: I have coded in JAL before, and I know that these tasks are far more
: complicated in JAL.

: Thank you for yo ur help. I will check out the PDFs you recommended.

Thu Dec 09, 2004 5:45 pm View user's profile Send private message
Brent



Joined: 20 Feb 2002
Posts: 57

Post Re: Calling a JAL script from Ruby Reply with quote

I just thought you would like to know that after getting back into this, I decided to re-write the process in VBScript.

I accomplished the lock detection with this function:

Function LockDetected(CompleteFileName)

Dim FileForLockTesting, ReturnValue

On Error Resume Next

Set FileForLockTesting = objFSO.OpenTextFile(CompleteFileName, 8, True)

If Err.Number 0 Then

ReturnValue = True

Else

FileForLockTesting.Close

Set FileForLockTesting = Nothing

ReturnValue = False

End If

On Error GoTo 0

LockDetected = ReturnValue
End Function

The rest was almost the same as the Ruby programming.

One question, could a save button be placed into the 24x7 editor?

: That sounds pretty simple. JAL is not a pretty language but it does the job.
: Here is how I would do it.

: 1 First of all create a new user defined method in the Script Library to
: check for file locked state. Let's call it IsFileLocked. This method would
: take one argument of string type for the file name and it will return
: boolean True/False indicating whether the file is locked or not. Example
: script: /////////////////////////////////////////
: OnErrorGoTo FILE_LOCKED
: Dim( temp, number )
: // Try to open file for reading (file_name is argument name)
: FileOpen( file_name, "LineMode", "Read", "",
: file_number )
: // If we are here we were able to open the file. Close it and return TRUE
: FileClose( file_number )
: Return( True )
: FILE_LOCKED: Return( False)
: ////////////////////////////////////////

: 2. Second I would create another method to check if the detail file is
: present and if yeas return file name, otherwise return an empty string.
: Let's call this method GetDetail, it will to have an argument for the
: header file name and it will return a string. This can be done as simple
: as the following: /////////////////////////////////////////
: Dim( len, number )
: Dim(detail_name, string )
: // header_name is an argument name. Let's calculate file name without
: _HDR.TXT suffix
: Length( header_name, len )
: Subtract( len, 8, len)
: // Build detail file name
: Left( header_name, len, header_name )
: Concat( header_name, "_RPT.TXT", detail_name )
: // Now, let's check if this file exists
: Dim( file_found, boolean )
: FileExists( detail_file, file_found )
: If Then( file_find, GOT_IT)
: Return( "" )
: GOT_IT: Return( detail_name )
: ////////////////////////////////////////

: 3. Third I would create another method to calculate the merge file name.
: Let's call this method GetReportName, it will have 2 arguments: detail
: file name and a target directory and it will return a string with the new
: file name. This could be done as simple as the following:
: /////////////////////////////////////////
: Dim( len, number )
: Dim( suffix, number )
: Dim( available, string )
: Dim( new_name, string )
: Dim( temp, string )

: // replace source dir with target dir in the file name
: SplitFileName( detail_name, temp, detail_name )
: Concat( target_dir, detail_name, detail_name )

: // Check if the name is available without suffix
: Set( new_name, detail_name)
: NotFileExists( new_name, available )
: IfThen( available, DONE )

: // Let's find an unique file number _RPT.TXT suffix ( If uniqueness is the
: only need and file name is not important, why not simply insert a
: timestamp suffix?)

: Length( detail_name, len )
: Subtract( len, 8, len)
: Left( detail_name, len, detail_name )

: // Now, let's roll
: LoopWhile True, END_LOOP
: Add( suffix, 1, suffix )
: ConcatEx( detail_name, suffix, "_RPT.TXT", new_name )
: NotFileExists( new_name, available )
: IfThen( available, DONE )
: END_LOOP: DONE: Return( new_name )
: ////////////////////////////////////////

: 3. Now here is the remaining part. Create job of script type, which will have
: a schedule [when certain files not found] and specify stop.txt file as the
: file to watch. In the job script code the following (all together it is
: less then 122 lines, including locking part and comemnts ):
: ////////////////////////////////////////////////////////////////////////////////////////
: Dim( header_list, string )
: Dim( header_file, string )
: Dim( detail_file, string )
: Dim( command, string )
: Dim( is_empty, boolean )
: Dim( file_lock, boolean)
: Dim( pid, number )

: // Get the list of all header files
: DirEx( "c:\\whatever\\*_HDR.TXT", header_list )
: // Loop through the list and check if detail is available and files are
: locked or not
: IsEqual( header_list, "", is_empty )

: LoopUntil( is_empty, END_LOOP )
: // Get next header file
: GetToken( ",", header_list, header_file )
: // Check for detail (see step 2 above)
: GetDetail( header_file, detail_file )
: IsEqual( detail_file, "", is_empty )
: IfThen( is_empty, TRY_NEXT_HEADER)

: // Check for locks
: IsFileLocked( header_file, file_lock)
: IfThen( file_lock, TRY_NEXT_HEADER)
: IsFileLocked( detail_file, file_lock)
: IfThen( file_lock, TRY_NEXT_HEADER)

: // Concat, copy and delete files
: GetReportName( detail_file, "c:\\whatever is target\\", target_file
: )
: ContactEx( "cmd /C copy \"", header_file, "\" +
: \"", detail_file, "\" \"", target_file,
: "\"", command)
: RunAndWait( command, "", 0, pid )
: FileDelete( header_file )
: FileDelete( detail_file )

: TRY_NEXT_HEADER
: // check if there are more files in the list
: IsEqual( header_list, "", is_empty )
: END_LOOP:
: ////////////////////////////////////////////////////////////////////////////////////////

Thu Dec 30, 2004 12:30 pm View user's profile Send private message
Display posts from previous:    
Reply to topic    SoftTree Technologies Forum Index » 24x7 Scheduler, Event Server, Automation Suite All times are GMT - 4 Hours
Page 1 of 1

 
Jump to: 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


 

 

Powered by phpBB © 2001, 2005 phpBB Group
Design by Freestyle XL / Flowers Online.