Rational Automation framework (RAF) has many and it would be impossible to cover everything in one product. At least out of the box. This is why RAF is such a powerful application. The ability the user has to answer their wildest automation dreams can come true. Custom actions can get overwhelming very quickly. I don't want to discuss this outside of the realm of the example I will provide. Via Twitter we had a request to know how to edit WebSphere property files instead of the config files. Since there are no actions directly related to modifying property files. I will walk you though creating a custom action to edit a property file.
Let's start from scratch and remove all expectations. Let's break down this custom action into several parts, not assuming the product can do anything on it's own. We need a list of parts we can target for discovery.
Start with a problem.
Problem:
How to get wsadmin to stop prompting for a userName and passWord when starting and stopping JVM's.
Through discovery we know this can be done by editing the soap.client.props file and removing the prompt value for wsadmin prompting and entering in a userName and passWord.
Parts:
-
What scope will the action run at.
-
Location of files needed to be changed
-
Type of script to write and how it will be executed.
-
ANT code
These four questions give a great place to start. No doubt many more questions will arise, but we have a good starting point. I will now answer each one in a separate section.
Scope:
Custom actions are saved to Ant build files in the user tree. Scope will determine where and how these actions will be ran, as well as what is necessary to run the action.
Before we go there. We should look at the rafw/product/actions directory. There are four folders, configure, deploy, install and model. This is where the out of the box product actions reside depending on their primary function. This structure mimics the RAFW_HOME user/actions directory. If we navigate to the user/actions directory we see the same four folders. Since, editing properties is more of a configure function. Inside the configure folder is a list of supported products. For this example, we will want to choose “was”. There are several version folders located in the was directory just like the product/actions have. You can place your action in a folder specific to a version. If this is an action for all versions, you can place it in the common folder, which will encompass all versions. For this example, we will be using the already created custom_configure_was_common.xml. Once this file is open, you will see several imports located at the top. These imports make various parts of the application available to your custom action in two major ways. For example:
<!-- Include cell properties -->
<property file="${CELL_PROPERTIES}" />
AND
<!-- import RAFW library -->
<import file="${RAFW_HOME}/product/lib/RAFW_lib.xml" />
The first example <property file> tag includes the cell properties file into our xml. The second example is an actual import. <import file> . This makes the rafw_lib.xml available to your custom action. This can be useful for logging with wsadmin commands that utilize the WebSphere admin objects. Doesn't apply to much for this example of editingn properties files.
Most of the imports have been created for you. The only thing to be careful with, is if you are creating a script and or batch file. Where are you going to place those files? You may want to include an import for the directory locations of your scripts if it does not already exist. You can also clarify the entire directory path of your script, just as long as the script resides somewhere in the rafw directory tree.
NOTE: in order for the files to be transferred to the target system. You must have your script or any other files used in the rafw/ directory and not on the local system.
For a properties file update, we can use the cell scope. This will be fine for our example. The scope can be initialized in the ANT code. Since this is a property file and not located via a typical WebSphere scope. The method we use to change the properties file doesn't really care about scope. It's not the same as running actions in wsadmin which rely on the scope.
For additional information on Scope and ANT build files. See the Info Center link below.
Location:
What is the properties file we want to change? Is that the only one we need to change? And where is it located?
For this example, we will be adding a userName and passWord as well as changing the wsadmin prompting method.
soap.client.props = IBM/WebSphere/AppServer/Profiles/DMGR/properties.
Now that I have the target file. Its time to make a backup of the properties file. Now that we have a problem to solve. We know what scope we will be running our action at. The location of our file to be changed and we know it's the only file needed for this functionality. The next step is to create our Jython script.
JYTHON
Let's break down our Jython Logic.
-
I need to locate the file in question and open that file
-
I need to read that file from top to bottom
-
As I read the file, I want to pick out certain keywords to identify
-
I then want to replace those values with different ones
I have created the Jython script below. Yes, there are many ways you could write this script. But since we are changing properties file, and If we don't want to run into any permissions issues. I chose to create a script to manipulate the file and launch it with a batch file.
This script will go in and read the backup of the soap.client.props file. I did this because, the original .props extensions are hidden for known folders in WebSphere. The script does not recognize soap.client by itself. If I search for soap.client.props, the script will find it. Except I am not changing the file and rewriting it. I am actually just reading the file and the output has all the changes. So I need to output the script to a file called soap.client, which will automatically get a props file extension. For if I name the file soap.client.props it will end up coming out soap.client.props.props. Which is wrong.
keyword = "com.ibm.SOAP.loginUserid=" keyword1 = "com.ibm.SOAP.loginPassword=" keyword2 = "com.ibm.SOAP.loginSource=prompt" psw = sys.argv[0] print 'Argument List:', str(sys.argv) hello = open("C:\Users\IBM_ADMIN\Desktop\soap.client.props", 'r+') text = hello.readlines() for line in text: if line.find('com.ibm.SOAP.loginUserid=') >= 0: b = keyword.replace("=", "=WSADMIN") print b.strip('\n') hello.flush() elif line.find('com.ibm.SOAP.loginPassword=') >= 0: c = keyword1.replace("=","=" + psw ) print c.strip('\n') elif line.find('com.ibm.SOAP.loginSource=prompt') >=0: d = keyword2.replace("=prompt", "=") print d.strip('\n') else: print line.strip("\n") hello.close() |
The next part to accomplish is our ANT code. To launch the batch script that will run my action. I discuss this more below, but next is the ANT code.
ANT Code
<rafwaction location="remote,transfer" name="was_common_change_soap_propsv2" executemode="true" augmentmode="true" comparemode="true" importmode="true" promotemode="true" /> <target name="was_common_change_soap_propsv2" description="This Actions takes the soap.client properties file from the WebSphere Application Server and creates a back up called soapclientbackup as a regular text file. The script will then read through the soap.client.props file, find the was username and password and replace it with whatever value is specified within the was_common_configure_soapClientProps.py script the script is located in the rafw/product/actions/was/common/scripts folder This action should only be ran one time and one time only."> <antcall target="execute"> <param name="EXECUTABLE" value="${RAFW_HOME}/user/actions/configure/was/common/scripts/ChangSoap.bat" /> </antcall> </target> </project> |
The <rafwaction> makes this action available for viewing in eclipse or through the command line using the -l argument. You do not need to include this element in your action but it's recommended. I set the modes by =true or =false. This is how the product will determine what modes the script can run in.
The <target> contains the name and a description of what my action might do. It also contains the chunk of code that will do all the work. The <Antcall> In this example. I have used the <antcall target=”execute”> to execute a changeProps.bat file. Now, in the example above. I have left the full file path to the batch file. If I import that scripts folder located {RAFW_HOME}/user/actions/configure/was/common/scripts/
I can change the execution value to changeProps.bat without the file path. For Example
<!--import the scripts folder location for my custom action-->
<import file="${RAFW_HOME}/user/actions/configure/was/common/scripts" />
Then my <antcall> looks like the one below.
<antcall target="execute">
<param name="EXECUTABLE" value="changeProps.bat" />
</antcall>
It can be done either way. Best practice would say to import the script location. So every time you create a custom action. You put the script to the action in the same folder for all custom actions.
Now that we have figured out our problem. Determined our scope, found the property files to edit, created a script to do that. Created an ANT script that executes a batch file. We need to create our .bat file. For example:
echo Creating a backup of your current Soap.clint folder. It will be renamed into a text file calld soapclientbackup copy C:\Progra~2\IBM\WebSphere\AppServer\profiles\Dmgr01\properties\soap.client.props C:\Progra~2\IBM\WebSphere\AppServer\profiles\Dmgr01\properties\soapclientbackup IF ERRORLEVEL == 1 ( echo Problem creating the soapclient file. Either the file does not exist or permissions are probably wrong.) else echo Deleting the existing soap.clint file after the backup was made. DEL C:\Progra~2\IBM\WebSphere\AppServer\profiles\Dmgr01\properties\soap.client.props IF ERRORLEVE == 1 ( echo Problem creating the soapclient file. Either the file does not exist or permissions are probably wrong.) else echo Launching the script soapClientProps.py and outputing the data with the username and password designated within the script to your new soap.client file call "C:\RAFW\product\actions\configure\was\common\scripts\was_common_configure_soapClientProps.py" >> "C:\Progra~2\IBM\WebSphere\AppServer\profiles\Dmgr01\properties\soap.client.props" IF ERRORLEVE == 1 ( echo Problem creating the soapclient file. Either the file does not exist or permissions are probably wrong.) else echo Completed successfully. |
This batch file will make a copy of the soap.client and rename is to soap.clientbackup. This file will have a file extension instead of a props extension. Now I have a soap.client.props and soap.clientbackup file. The batch file will then delete the soap.client.props and call the Jython script, which goes and reads the soap.clientbackup file and outputs the new data to a soap.client.props. This eliminates potential permissions issue when overwriting property files.
The location of the batch file is located in the user/actions/scripts folder. I created the scripts folder in the user/actions/configure/was/ directory to hold my batch file. My actual Jython script could be put into the same folder but I chose to put mine in the rafw/product/script folder. But in either case, as long as you declare the file path and or import that directory into your xml, everything should work.
That is pretty much all you need to know when creating custom actions to edit property files.
Below is the link to all the custom action information. If you would like more in depth information regarding wsadmin admon objects and how to manipulate them. Please visit our twitter
And let us know what you want to hear.