Chris Malek is a PeopleTools® Technical Consultant with two decades of experience working on PeopleSoft enterprise software projects. He is available for consulting engagements.
About Chris Work with ChrisIntroducing a small but powerful PeopleSoft bolt-on that makes web services very easy. If you have a SQL statement, you can turn that into a web service in PeopleSoft in a few minutes.
The OnRouteSend
event triggers before the publication contracts are created and allows you to remove or modify the contracts that are created programmatically. You can inspect the message content and override Service Operation routings. We use this OnRouteSend
to override node publication and selectivity not publish to certain nodes at certain times. This is used for asynchronous service operations
.
The comments in the interface definition have some good information:
/* This interface is the equivalent of the OnRouteSend and OnRouteReceive
PeopleCode events in 8.4x tools. OnRouteSend will pass in a message to
your derived application class method. The return should be an integer.
%IntBroker_ROUTE_NONE = Do send this operation to any of the possible nodes
%IntBroker_ROUTE_SOME = Send this operation to a selected list of nodes.
The node list should be an array of strings in the property "destinationNodes".
%IntBroker_ROUTE_ALL = Send this operation to all nodes that have a valid routing.
OnRouteReceive will pass in a message to your derived application
class method. The return should be a Boolean.
FALSE = The Operation will not run locally
TRUE = The Operation will run locally.
If an error occurs the OnError method if implemented will be
automatically invoked. The type of exception can be viewed by using the
Message object to retrieve the Exception object (&Message.IBException).
Please see the PeopleCode Language Reference guide for
more information about the Exception class.
*/
interface IRouter
method OnRouteSend(&message As Message) Returns integer;
method OnRouteReceive(&message As Message) Returns boolean;
method OnError(&request As Message);
property array of any destinationNodes;
end-interface;
In my testing even if you return %IntBroker_ROUTE_NONE
, local subscriptions will trigger still. You can’t use this to stop local subscriptions from processing in a local operation instance. You have to do something like this in the subscription handler.
If &_MSG.IsLocal And
&_MSG.IBInfo.OrigNode <> &_MSG.IBInfo.SourceNode Then
do not run code because this is a secondary operation instance that got triggered
OnRouteSend
will pass in a message to your derived application class method. The return should be an integer.
%IntBroker_ROUTE_NONE
= Do send this operation to any of the possible nodes%IntBroker_ROUTE_SOME
= Send this operation to a selected list of nodes
destinationNodes
property array of strings that reflect the real node name that should receive the message. So if the Integration broker routing table says that 4 nodes get the message and the code determines that there is one node that should NOT get the message then you need to insert the 3 nodes that should get the message.%IntBroker_ROUTE_ALL
= Send this operation to all nodes that have a valid routing.The following is an example handler where the client was setup in a very specific way. Each PeopleSoft NODE had a different OPRID attached. It was trying to stop PERSON_BASIC_SYNC messages from being published outbound that were created by other inbound messages. Basically, this handler says: “If the message was created by the current integration broker user then do NOT publish outbound because the external system already sent it and this message was created from the CI update.”
Do NOT put this code in use unless you fully understand what it is doing.
import PS_PT:Integration:IRouter;
class stopBoomerang implements PS_PT:Integration:IRouter
property array of any destinationNodes;
method OnRouteSend(&msgParm As Message) Returns integer;
method getIBRoutings(&msgParm As Message) Returns array of string;
end-class;
method getIBRoutings
/+ &msgParm as Message +/
/+ Returns Array of String +/
Local array of string &targetNodes = CreateArrayRept("", 0);
Local Rowset &IBroutes = CreateRowset(Record.PSIBRTNGDEFN_VW);
Local number &index, &rowCount;
&rowCount = &IBroutes.Fill("WHERE FILL.IB_OPERATIONNAME = :1 AND FILL.EFFDT = (SELECT MAX(B.EFFDT) FROM PSIBRTNGDEFN_VW B WHERE B.IB_OPERATIONNAME = FILL.IB_OPERATIONNAME AND B.EFF_STATUS = 'A') AND FILL.EFF_STATUS = 'A'", &msgParm.OperationName);
For &index = 1 To &rowCount
&targetNodes.Push(&IBroutes(&index).PSIBRTNGDEFN_VW.RECEIVERNODENAME.Value);
End-For;
Return &targetNodes;
end-method;
method OnRouteSend
/+ &msgParm as Message +/
/+ Returns Integer +/
/+ Extends/implements PS_PT:Integration:IRouter.OnRouteSend +/
/***********************************************************************\
* Send to all, none or some destinationNodes: *
* %IntBroker_ROUTE_SOME; must then set array of any destinationNodes *
* %IntBroker_ROUTE_ALL *
* %IntBroker_ROUTE_NONE *
/***********************************************************************/
Local string &sReceiverNodeName;
%This.destinationNodes = CreateArrayAny();
Local boolean &bByPassingAReceiverNode = False;
Local array of string &aFullRoutingNodeList;
&aFullRoutingNodeList = %This.getIBRoutings(&msgParm);
Local integer &i;
Local string &sGetNodeUser, &sNodeUser;
&sGetNodeUser = "SELECT USERID FROM PSMSGNODEDEFN WHERE MSGNODENAME = :1";
For &i = 1 To &aFullRoutingNodeList.Len
SQLExec(&sGetNodeUser, &aFullRoutingNodeList [&i], &sNodeUser);
If &sNodeUser = %OperatorId Then
&bByPassingAReceiverNode = True;
Local string &sMsg;
&sMsg = "Bypassing node: " | &aFullRoutingNodeList [&i] | " because the node sent the orignal update.";
MessageBox(%MsgStyle_OK, "", 0, 0, &sMsg);
Else
%This.destinationNodes.Push(&aFullRoutingNodeList [&i]);
End-If;
End-For;
&aFullRoutingNodeList = Null;
If %This.destinationNodes.Len = 0 Then
Return %IntBroker_ROUTE_NONE;
Else
If &bByPassingAReceiverNode = False Then
/* No Boomerange condition found */
Return %IntBroker_ROUTE_ALL;
Else
Return %IntBroker_ROUTE_SOME;
End-If;
End-If;
end-method;