8.0 Instrumenting Generated Code

 


8.1  Instrumentation overview

8.2 Generated Code Structure

8.2.1 TL1 Agent Main File

8.2.2 Source Files

8.2.3 Conf Files

8.2.4 Handler Files

8.3 Instrumenting the Generated Code

8.4 Code Merging


 

8.1 Instrumentation Overview

 

Instrumentation is done in the TL1Agent to get the actual values from your device/ application .This chapter explains the process of adding the actual functionality to the generated code, so that the agent responds with the desired information .  Upon Instrumentation, the agent will send the appropriate response to the manager for the incoming message.

 

8.2 Generated Code Structure

 

The TL1 Compiler expects a TCS file in XML format as the input. For an input TCS, following files will be generated

8.2.1 TL1 Agent Main File

 

The default name of the main file is WebNMSTL1Agent.java.  This file can be found inside the <Agent Toolkit Home>/tl1projects/<Your Project>/agent/src directory.

 

This file is the main file for the TL1 Agent. This file takes care of registering all the commands with the command Registry. This file contains methods that initialize the TL1Agent and take care of registering the command codes in the Command Registry and returning their instances.

 

Also, you can enable/disable and configure the settings of TL1 Agent features Self Monitoring, Built-in-Commands, Asynchronous Message processing, and Security  from the WebNMSTL1Agent.java file.

 

8.2.2 Source (src) Files

 

Two types of source files are generated when code is generated for any TCS file from the TL1 Compiler:

They are explained in following sections

 

Input Message Source Files: These are src files generated for the input message type command codes. The Input Message type src Files contain two methods - getAck() and DoAction()

 

getAck():This method will be called from the TL1Engine before processing the TL1 input message. You can instrument the getAck() method to receive appropriate Acknowldgement Messages. You can return appropriate Acknowledgement codes codes based on your requirement by using the static variables defined in the com.adventnet.tl1.message. TL1AckMessage class. If "null" is returned, then no acknowledgement is sent by the TL1 agent.

 

Following Code snippet shows a sample getAck() method

doAction(): This method will be called by the TL1Engine for processing the input Message. This method will return a TL1Agent ResponseInfo, which contains the response values, the line types, and all the required information to form the response. You can write your code here to instrument and get the desired response. Following information will be useful for instrumenting the doaction() method to process the input message. A sample doAction() method is available in chapter 8.3 of this section

 

a. Parameter for Getting the Input Message Information

 

The incoming request information can be retrieved from the TL1AgentRequestInfo(), which is passed as a parameter to the doAction() method. All the major parameters of the Input Message such as the verb, modifiers, AID, C-Tag, MPB, etc., can be retrieved. You can refer to the JavaDocs for the information that can be retrieved from the TL1AgentRequestInfo().

 

<TL1AgentRequestInfo>.getMessagePayload() will return a Vector array.  Each element in the array represents a Block and each element in the Vector represents the parameters.

 

b. Getting the Access Identifier Information

 

The generated code also gives the incoming AccessID in the form of a <verb>_<modifier1>_AID class object. The <verb>_<modifier1>_AID.java also gets generated if an AID is defined for that command code. TL1 Agent supports all the valid AID syntaxes. The valid syntaxes are:

x

x, y

x-y-z-....

x&y&z&...

x&&y

x-y-z-...&-a&-b&-...

x-y-z-...&&-a

 

Based on the syntax of the Access ID, code is generated. The AID object is defined as public.

public AUD_EQPT_AID[] accessId = null;

 

For example, if the Command code is AUD-EQPT and the AID syntax is "x,y", then the code will be generated as follows:

      accessId = new AUD_EQPT_AID[1]; 

      accessId[0] = new AUD_EQPT_AID(aidVector);

The AUD_EQPT_AID contains 2 variables with the names as defined in the tcs. In this case - x and y.

 

The incoming AID values can be retreived from this AUD_EQPT_AID object reference.

 

For example, if the incoming AID is 10,12 then accessId[0].x will be 10 and accessId[0].y will be 12.

 

Suppose if the AID syntax is x-y&-z, then the code generated would be as follows.

In the AUD_EQPT_AID, only x and y are defined because,  y and z should be of the same type for this AID. If the incoming AID is phase 25 & 30 then the individual values can be retrieved as follows :

      for(int i=0; i<accessId.length; i++) { 

      System.out.println(accessId[i].x+"   "+accessId[i].y); 

      }

The output for the above code will be as follows:

 

phase 25

phase 30

 

c. Forming the Request Block Information :The doAction() method returns a TL1AgentResponseInfoobject. This contains the necessary information to form and send the Response message. A sample code of forming the TL1AgentResponseInfo would be as follows:

Similar code is generated by default in the Response src  files. You can instrument those to send the appropriate response. 

 

The completion code can also be set in the TL1AgentResponseInfo as follows:

      responseInfo.setCompletionCode(com.adventnet.tl1.message.

      TL1ResponseMessage.DENIED);

Thus, the static variables defined in the com.adventnet.tl1.message.TL1ResponseMessage class could be used for sending the Completion Code. If no Completion Code is specified in the responseTable, then the default completion code will be taken as com.adventnet.tl1.message.TL1ResponseMessage.COMPLETED

 

Also, a TL1AgentException can be thrown from within the doAction() method (Note that the doAction() throws TL1AgentException). This is converted to an error message as the response. The completion code will automatically be set to DENY. The error code has to be specified while throwing an exception. Static variables are defined in Class TL1Errors for specifying the error code. The code for throwing a sample exception would be as follows.

This throws an INVALID ACCESS IDENTIFIER error message with the completion code as DENY. Further explanation on error messages can be found in the troubleshooting section.

 

Autonomous type Source Files: Autonomous src files are generated for the output codes defined in the TCS file. The Autonomous message type src file contains the below method.

 

public void sendAutonomous ( )

 

This method can be called from the application code which is interested in sending alarm to TL1 NE.   The TL1AgentResponseInfo passed as a parameter in this method will be set as the User Data in the autonomous message. This autonomous message  will be caught and converted to TL1 autonomous message by the TL1Engine.  Please refer to Java Docs for more information.

 

Please refer to section 9.0 on Sending Autonomous Messages for more details.

 

The static variables defined in the com.adventnet.tl1.message.TL1AutonomousMessage class could be used for sending the Alarm Code. If no Alarm Code specified in the userData table is set in the autonomous message, then the default alarm code will be taken as com.adventnet.tl1.message.TL1AutonomousMessage.MAJOR_ALARM

 

8.2.3 Conf Files

 

Conf files for all the security views are available in the WebNMS\JavaAgent\tl1projects\<Your Project>\agent\bin\conf directory.  Also a text file for logging security related information namely SecurityLog.txt file will be available in this directory. Following are the text files that are available in the directory.

These files are generated depending on the security configuration in the TL1 Compiler settings. The conf files will be in text format.

      Note: These files should NOT be altered by the user. These are provided for persistence

      storage and not for reconfiguring the settings.

8.2.4  Handler Files

 

When Resource and/or Operations-Related security is enabled in the TL1 Compiler before code generation, the respective handler files will be generated in the JavaAgent\tl1projects\<Your Project>\agent\handler directory. i.e. ResourceSecurityHandler.java file will be generated when resource security is enabled and OperationSecurityHandler.java file will be generated when Operations-Related security is enabled.

 

You can instrument these handler files to make the Operations security view and Resource view to respond in a way that you require.

 

You can use these files to check the necessary conditions to be satisfied for the respective security.

 

When Resource security and Operation security are  selected, the methods CheckPostForResourceSecurity() and CheckPostForOperationSecurity() are called respectively. If other security views are selected along with User Security, the corresponding set methods with corresponding information are called. So, these information can be obtained using getters.

 

You have to instrument the checkPostFor<Resource/Operation>Security() method in the same way security restrictions are achieved for resource security. By default the checkPost method returns true.

 

If you wish to send any error message when the security restrictions are violated, an exception can be thrown as follows.

 

throw new TL1AgentException("Error occured",TL1Errors.ICNV)

 

Here, the key is the resource name, and the value is TL1ResourceSecurity object. The Resource security related information can be obtained from that.

 

8.3  Instrumenting the Generated Code

 

After generating the src files and testing any prototype agent, the next step would be to instrument those files to communicate with the device and perform the necessary operations. The appropriate response to be sent to the manager for the incoming message needs to be filled in the generated Response src files.

 

The doAction() of a sample Response src file looks like as follows :

 

/**

* This method will be invoked by the TL1 NE for processing the input Message.

* User can do his instrumentation here as how he needs to have the response.

* If the user needs to send any autonomous messages defined here he can just

* call the method sendAutonomous() for the corresponding autonomous messages

* using the get method for it's reference in the main file.

* @return A TL1AgentResponseInfo which contains the response values, the line

* types and all the required information to form the response.

*/

public TL1AgentResponseInfo doAction(TL1AgentRequestInfo reqInfo)

throws TL1AgentException {

/** Default Response **/

/** Implementation for selected types **/

String[] responseKeys = null;

boolean[] nameEqVal = null;

Object[] defaultRespValues = null;

String[] delimiters = null;

TL1Line line = null;

Vector responseVector = new Vector();

responseKeys = respKeys[0];

//defaultRespValues = defaultValues[0];

/* Implementation for QUOTED type */

defaultRespValues = new Object[2];

defaultRespValues[0] = System.getProperty("os.name");

defaultRespValues[1] = System.getProperty("os.version");

delimiters = respDelimiters[0];

nameEqVal = nameEqualsValue[0];

line = TL1MessageFormatter.createTL1Line(responseKeys,defaultRespValues,delimiters,lineTypes[0],nameEqVal);

responseVector.add(line);

responseKeys = respKeys[1];

//defaultRespValues = defaultValues[1];

/* Implementation for UNQUOTED type */

defaultRespValues = new Object[1];

defaultRespValues[0] = System.getProperty("user.name");

delimiters = respDelimiters[1];

nameEqVal = nameEqualsValue[1];

line = TL1MessageFormatter.createTL1Line(responseKeys,defaultRespValues,delimiters,lineTypes[1],nameEqVal);

responseVector.add(line);

responseKeys = respKeys[2];

//defaultRespValues = defaultValues[2];

/* Implementation for COMMENT */

defaultRespValues = new Object[1];

defaultRespValues[0] = "These informations are taken from the machine where agent

runs ";

delimiters = respDelimiters[2];

nameEqVal = nameEqualsValue[2];

line = TL1MessageFormatter.createTL1Line(responseKeys,defaultRespValues,delimiters,lineTypes[2],nameEqVal);

responseVector.add(line);

TL1AgentResponseInfo responseInfo = new TL1AgentResponseInfo();

responseInfo.setResponseLinesVector(responseVector);

return responseInfo;

}

 

As seen from the above code, by default (i.e., without any instrumentation) the agent will send some default values as per the type in the response message.

 

You can add your own code below the comment ,

 

  *   Add your code below this comment for doing the         *

  *   necessary action and form the TL1AgentResponseInfo. *

 

and fill the response values in the responseLines Hashtable.

 

Also, you can send multiple lines in the Response Message. For more information, please refer to the examples under the <Agent Toolkit Home>/examples/tl1 directory.

 

8.4  Code Merging

 

Code merging, is an option provided for users who prefer to shift between releases. It is mainly used for migration purposes. Say, if a developer using 4.0 version of Agent Toolkit decides to migrate to the 4.2 version, then he can make use of this

Merging option wherein the manually added code (using the tags) is merged with the code, present in the file generated by the new version of the toolkit, to attain the functions available in the old version.

 

The user code is normally  added to the generated files using the following tags.

 

// User code starts here

//Add your code here....

// User code ends here

 

OR

 

/* User code starts here */

Add your code here

/* User code ends here */

 

OR

 

// WebNMS code ends here

// Your code can be added here

// WebNMS code starts here

 

These are the custom tags which can be used anywhere in the generated code. The user has to just include his code in the file with these tags. When regenerated, the MibCompiler looks for these tags and preserves the changes in the newly generated code. If  either of the tags are not given merging will not be proper. Please note that the last tags

are also supported and when these get generated in certain files, the user has to just include the codes between these tags which is generated, by default. Thus code merging is supported on all generated java files.

 

In our earlier releases, when regenerating the source code,  the existing src files will be overwritten or will remain untouched based on the option selected by the user in the MibCompiler UI. And this was totally based on string comparison. Normally

we take the user codes by identifying the user code tags. The line prior to the "starting user tag" is taken as the reference string. The number of occurrences of the reference string in that file from the beginning is taken into account. This reference string (and occurrence) has to be located in the new file. It is added below the reference string in the new file as per the reference string count. If we are not able to locate the reference string in the new file, it will be added at the end of the file. This type of merging has the following constraints :-

....

....

void method1()

{

int i=0;

i=i+10;

}

 

void method2()

{

int j=0;

for(int i=0; i<10; i++)

j=j+i;

}

 

//User code starts here

int k=10;

//User code ends here

.....

.....

 

As said in the old file, the code within the tags should be present in the second method [void method2()] of the new file, after merging. The reference line for the user code is "}" and the number of occurrences of this character is 2 in the whole

file. After regenerating, though it should be added in the 2nd method, considering the count of references specified in the old version , the method is erroneously added before the 2nd method. And, the new file appears as below, after regeneration.

 

....

....

void method1()

for(int k=0; k<15; k++)

System.out.println("k value is +

"+k);

 

for (int i=0; i<0; i++) 

{

System.out.println("I value is +"

+i);

}

 

int i=0;

i=i + 10 ;

}

 

//User code starts here

int k=10;

//User code ends here

 

void method2()

{

int i=0;

for (int i=0; i<0 ; i++)

{

j=j+i;

}

The user code should have been added here

....

....

 

 

Enhancements in Code Merging

 

To overcome all these problems a much better merging has been used. As per this option, the entire java file is converted into a sequence of tokens. This  sequence of tokens exists for both the old file and the new file.

 

A set of "Productions" is defined while parsing the java file and each production contains reference tokens called as the starting token and ending token. Each production might be like package, imports, classInfo, methods, variables and so on. Using this Production concept the entire java file is split into a number of parts as Package part, Import Part, ClassInfo Part, Methods part, etc.,. While merging option is chosen, the respective part alone is taken for checking and the method or variable is added in its exact place or at the end of that section (if reference string is not available). Hence merging is based on method level merging. This saves a lot of time also.

 

When merging option is chosen the entire java file is not searched for the reference token, instead the respective methods in which the reference token is present is considered. In case, the user tags are not available in the old file then the code

is added just below that method and not at the end of the file.

 

Also, please note that, each token contains some special tokens which denotes the comments, spaces and empty lines available above the tokens.  For merging purposes, these special tokens in each token of the old file is considered and there after it searches for the user code starting tag. If it is available, then the following sequence of tokens is taken as user code tokens, up to the token which contains user code end tag in its special token. Then the following sequence of token's value is taken as reference string up to the token which contains new line character in its special token.

 

Now the reference string in the new file is searched for, by getting the information from tokens. After locating the proper place in the new file, the tokens are inserted (which are the user codes) above the starting reference token in new file. Please note, from this release the last line is considered as the reference line for code merging.

 

 

Copyright © 2009, ZOHO Corp. All Rights Reserved.