/* This program demonstrates dynaTrace CICS ADK APIs. */ /* One group of APIs contains functions for starting and * ending a Purepath for the transaction and associated tagging * functions. A newer group of APIs permits nodes to be inserted * into a Purepath that is already in progress and to capture * its arguments or return value. The two groups of APIs are * unrelated, but they can be used within the same transaction. */ #include #include #include #include /* ADK Header, DTSTUB object */ short int sum( char *); long int resp; /* EXEC CICS command response */ /*-------------------------------------------------------------------*/ /* SUM Function */ /* This routine is a stand-in for an external call. */ /*-------------------------------------------------------------------*/ short int sum(char *tag) { short int m, n, r; long int rc, msg_len; char op_msg[80]; short int msg_rc; long int token; char * argument = "Hello."; long int argccsid = 0; char * nodename = "TESTPROG"; memset(op_msg,'\0',sizeof(op_msg)); /*----------------------------------------------------------------*/ /* Start the linked path. If your CICS transaction receives a */ /* dynaTrace tag from another platform, a DTSLP* API is all that */ /* is required to trace the transaction and any other CICS */ /* transactions that it starts through a supported protocol. */ /*----------------------------------------------------------------*/ rc = DTSLPTN(tag); if (rc != 0) { sprintf(op_msg,"DTSLPTN API returned RC %i", rc); msg_len = strlen(op_msg); EXEC CICS WRITE OPERATOR TEXT(op_msg) TEXTLENGTH(msg_len) RESP(resp); memset(op_msg,'\0',sizeof(op_msg)); } /* End of error DTSLPTx ADK call */ /*----------------------------------------------------------------*/ /* Simulate calling another program by inserting another node */ /* into the Purepath here. A Data Capture API is used to specify */ /* a string argument. Note that these functions are unrelated */ /* to the tagging functions that are also being demonstrated */ /* elsewhere in this program. */ /* */ /* The token value must be retained and supplied on the matching */ /* Exit API. If nested nodes are created, each will have its own */ /* token and the most recent one must be exited first. */ /* */ /* Start by capturing an argument for the simulated program node. */ /*----------------------------------------------------------------*/ rc = DTDCTN(argument, &argccsid); if (rc != 0) { sprintf(op_msg,"DTDCTN API returned RC %i", rc); msg_len = strlen(op_msg); EXEC CICS WRITE OPERATOR TEXT(op_msg) TEXTLENGTH(msg_len) RESP(resp); memset(op_msg,'\0',sizeof(op_msg)); } /* End of error DTDCTN ADK call */ /*----------------------------------------------------------------*/ /* Enter the simulated program. */ /*----------------------------------------------------------------*/ rc = DTENTN(nodename, &token); if (rc != 0) { sprintf(op_msg,"DTENTN API returned RC %i", rc); msg_len = strlen(op_msg); EXEC CICS WRITE OPERATOR TEXT(op_msg) TEXTLENGTH(msg_len) RESP(resp); memset(op_msg,'\0',sizeof(op_msg)); } /* End of error DTENTN ADK call */ /*----------------------------------------------------------------*/ /* The application work associated with this program goes here. */ /*----------------------------------------------------------------*/ r = 8; /*----------------------------------------------------------------*/ /* End the program node that we added with a return code 8. */ /* */ /* Start by capturing the return value. */ /*----------------------------------------------------------------*/ rc = DTDCS(&r); if (rc != 0) { sprintf(op_msg,"DTDCS API returned RC %i", rc); msg_len = strlen(op_msg); EXEC CICS WRITE OPERATOR TEXT(op_msg) TEXTLENGTH(msg_len) RESP(resp); memset(op_msg,'\0',sizeof(op_msg)); } /* End of error DTDCS ADK call */ /*----------------------------------------------------------------*/ /* Exit from the simulated program using the token from the most */ /* recent Enter API. */ /*----------------------------------------------------------------*/ rc = DTEX(&token); if (rc != 0) { sprintf(op_msg,"DTEX API returned RC %i", rc); msg_len = strlen(op_msg); EXEC CICS WRITE OPERATOR TEXT(op_msg) TEXTLENGTH(msg_len) RESP(resp); memset(op_msg,'\0',sizeof(op_msg)); } /* End of error DTEX ADK call */ /*----------------------------------------------------------------*/ /* End the linked path before returning. */ /*----------------------------------------------------------------*/ rc = DTEP(); if (rc != 0) { sprintf(op_msg,"DTEP API returned RC %i", rc); msg_len = strlen(op_msg); EXEC CICS WRITE OPERATOR TEXT(op_msg) TEXTLENGTH(msg_len) RESP(resp); memset(op_msg,'\0',sizeof(op_msg)); } /* End of error DTEP ADK call */ return r; } /* End of SUM Function */ /*-------------------------------------------------------------------*/ /* MAIN program section */ /*-------------------------------------------------------------------*/ main() { /* Optional name to describe the initial path. */ char pathname[100] = "Started from tagging ADK"; /*---------------------------------------------------------------*/ /* Buffer to hold the tag that will identify a child path. */ /* Note: DynaTrace 5.x requires a buffer of at least 77 bytes. */ /*---------------------------------------------------------------*/ char tag_buffer[100]; /* Tag data buffer. */ short int txt_len; long int tag_buffer_len; long int ccsid = 0; char term_msg[] = "C TAGTEST Complete."; long int rc, msg_len; char op_msg[80]; short int from = 1, to = 10, s, msg_rc; memset(tag_buffer,'\0',sizeof(tag_buffer)); tag_buffer_len = sizeof(tag_buffer); txt_len = sizeof(term_msg); memset(op_msg,'\0',sizeof(op_msg)); /*----------------------------------------------------------------*/ /* Start an initial path for this transaction. */ /* */ /* The first parameter is a null terminated string, */ /* The second parameter is its code page. */ /* Zero indicates the default code page of the CICS region. */ /*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/ /* Note that a transaction that receives a tag from a program */ /* running on another platform should start a linked path instead */ /* so it can set a tag. For an example, see subroutine SUB1 */ /* below. */ /*----------------------------------------------------------------*/ rc = DTSPTN(pathname, &ccsid); if (rc != 0) { sprintf(op_msg,"DTSPTN API returned RC %i", rc); msg_len = strlen(op_msg); EXEC CICS WRITE OPERATOR TEXT(op_msg) TEXTLENGTH(msg_len) RESP(resp); memset(op_msg,'\0',sizeof(op_msg)); } /* End of error DTSPTx ADK call */ /*----------------------------------------------------------------*/ /* Note: */ /* Any activity that occurs in this transaction between a start */ /* path or start linked path API and the next DTEP API will be */ /* associated with the started path. Optionally, insert link APIs */ /* can be used to create tags to represent subpaths for children */ /* of this transaction. The CICS agent automatically tags CICS */ /* transactions started by DPL LINK or START requests made by any */ /* traced transaction, so insert link is typically used to tag */ /* service requests made to programs running on non-CICS platforms*/ /*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/ /* Insert a link for a child path to trace a service request to a */ /* program that will run on another platform. The tag length must*/ /* be initialized to the size of the buffer to hold the tag that */ /* will be returned. */ /*----------------------------------------------------------------*/ rc = DTILTN(tag_buffer, &tag_buffer_len); if (rc != 0) { sprintf(op_msg,"DTILTN API returned RC %i", rc); msg_len = strlen(op_msg); EXEC CICS WRITE OPERATOR TEXT(op_msg) TEXTLENGTH(msg_len) RESP(resp); memset(op_msg,'\0',sizeof(op_msg)); } /* End of error DTILTx ADK call */ /*----------------------------------------------------------------*/ /* Note: */ /* Pass the tag that was obtained above to the service to identify*/ /* the path that it will set to report its activity. */ /*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/ /* End the initial path early because one transaction can't be */ /* linked to two paths at once. Normally this API would be used */ /* when the transaction is finished or when it wants to start */ /* another path to trace a new unit of work. */ /*----------------------------------------------------------------*/ rc = DTEP(); if (rc != 0) { sprintf(op_msg,"DTEP API returned RC %i", rc); msg_len = strlen(op_msg); EXEC CICS WRITE OPERATOR TEXT(op_msg) TEXTLENGTH(msg_len) RESP(resp); memset(op_msg,'\0',sizeof(op_msg)); } /* End of error DTEP ADK call */ /*----------------------------------------------------------------*/ /* To avoid the inconvenience of defining additional transactions */ /* and programs, we will call an embedded subroutine here instead */ /* of making a request to an external service. */ /*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/ /* Perform some calculations */ /*----------------------------------------------------------------*/ s = sum(tag_buffer); /*----------------------------------------------------------------*/ /* Send a message to the terminal and return to CICS. */ /*----------------------------------------------------------------*/ EXEC CICS SEND TEXT FROM(term_msg) LENGTH(txt_len) ERASE RESP(resp); EXEC CICS RETURN; /* This returns control to CICS. */ return; } /* End of ADKC program. */