Edit Content

Novitates Tech is committed to shaping a digital landscape that empowers businesses globally, offering accessible transformative solutions that ignite industry-wide change. Our dedication to innovation drives us to create strategies that redefine global business operations.

Get in touch

Introduction 

As part of embedding a work case link in email, with Theme-Cosmos we have OOTB rules helping us with Correspondence fragments which dynamically generate the link. 

However, with constellation the same approach might not work in a full-fledged manner leading to various anomalies. This is due to the reason that Constellation apps support semantic URLs by default. To launch a case using a URL, you should construct it using the semantic URL pattern supported by the Constellation UI. 

The same problem statement has been highlighted in the below PDN article as well 

https://support.pega.com/question/case-link-email-not-working-constellation? 

Implementation 

With constellation, the URL used to access the work case differs when compared to Theme-Cosmos as shown in the below picture 

URL Pattern: https://baseurl/prweb/app/event/processes/P-11006?portal=WebPortal 

Case Type: Process 

This new semantic URL must be dynamically formed where below 3 steps must be handled, 

  1. The base URL until the appalias name must be dynamically formed with OOTB java code. 
  2. Case type name with additional “s” must be dynamically fetched 
  3. The portal name which is seen as the query string parameter must be parameterized to redirect users to the correct portal. 

To encapsulate the above tasks into one rule, we can build a function rule with certain parameters that does all the heavy-lifting and returns us the URL as final output. 

Reusable Function 

Let’s call this function as “GetCaseLinkURL” which will intake 4 arguments as mentioned below, 

  1. tools – PublicAPI 
  2. caseID – pyID of your work case 
  3. className – pxObjClass of your case type 
  4. portalName – portal name where the case should be opened for viewing. If not passed, default will be “WebPortal 

As part of this function logic, below are the important tasks we are going to perform in detail. 

Building base URL 

We can use the OOTB class methods to build the base URL for the current application context using the below code 

com.pega.pegarules.pub.session.url.PegaURLBuilder pegaURLBuilder = pega.getExternalURLBuilder(); 

publicURLString = pegaURLBuilder.usePublicLink().currentApplication().build(); 

The above code will give us the URL until the appaliasname based on the current application context.  

For eg. https://baseurl/prweb/app/event 

The above piece of code is already used in the OOTB correspondence fragment rules in Theme-Cosmos as well. Strangly, the piece of code highlighted in yellow works in Correspondence Fragment and Activity’s Java step but does not work in Function rule.  

But without using these two lines we cannot fetch the current application context URL. So, we can write these two lines in a Java step in an activity in baseclass and call it in the reusable function we are building. 

So, we have written an activity in baseclass with name “GetPublickLinkURL” as shown below, 

Activity execution will build the URL and pass back the Public Link URL as out parameter which is fetched and used further. 

This function will be called in the first of the function as shown below 

The above activity can be named as per choice of naming convention. If we can figure out the way to build the public link URL based on the current application context in function itself, then we need not use this activity at all. 

Fetching the Case type name 

A new OOTB rule type is introduced in Constellation which is “Rule-UI-Routing” one per application which is created automatically once the application is created. 

We have noticed that all the case type names are stored automatically in this rule type as and when the case types are generated. Also, this rule type plays a major role w.r.t to Constellation working methodology as well. Due to that it is recommended to generate this routing table using a button on the application rule, if the “pyRoutingTable rule is not present in your application ruleset or not updated properly. 

pyRoutingTable does not have a UI but it does have a JSON string in on the property named “pyRoutes” as shown below. 

So, if we want to fetch the plural case type name dynamically, we must use the case type class as input and parse the JSON. 

As part of the function, we open the pyRoutingTable instance and pull the JSON and parse it using Jackson API to fetch the caseName based on the className passed as parameter. 

Using Portal name as parameter 

PortalName is one of the parameters for the function which we have developed so that we can embed the same into the URL as a query string parameter. If no value is passed, then WebPortal is taken as a default. 

Based on the above 3 elements, the final URL is formed and returned as output 

Benefits of the function 

  1. This function would serve as one stop shop to fetch the URL throughout the application without the need to write additional java code to build the URL 
  2. As this function is parameterized with className, caseID and portalName, it can be used from anywhere in the application by passing appropriate values. 
  3. This function can also be extended to build the Theme-Cosmos URL pattern as well. 

Function code 

//Get the Param.PublicLinkURL out of this activity execution  

  boolean urlExec = pega_rulesengine_utilities.pxExecuteAnActivity(tools.getPrimaryPage(), “GetPublickLinkURL”); 

  String semanticURL = tools.getParamValue(“PublicLinkURL”); 

//Open the routing table instance 

  String routingRuleName = “pyRoutingTable”; 

  StringMap aKeys = new HashStringMap(); 

  aKeys.put(“pxObjClass”, “Rule-UI-Routing”); 

  aKeys.put(“pyRuleName”, routingRuleName); 

  ClipboardPage routingPage = null; 

  try { 

    routingPage = tools.getDatabase().open(aKeys, true); 

  } 

  catch(DatabaseException e){ 

    throw new PRRuntimeException(e); 

  } 

//Get the pyRoutes property value out of the routing table 

  String routeString = routingPage.getString(“pyRoutes”); 

  ObjectMapper mapper = new ObjectMapper(); 

  JsonNode arrayNode = null; 

  String caseTypeName= “”; 

//Loop through the JSON using jackson api to fetch the relevant caseName 

  try{ 

  { 

      arrayNode = mapper.readTree(routeString); 

      List<JsonNode> payloads = arrayNode.findValues(“payload”); 

      for(JsonNode node: payloads){ 

           Iterator<Map.Entry<String, JsonNode>> fields = node.fields(); 

           while (fields.hasNext()) { 

          Map.Entry<String, JsonNode> jsonField = fields.next(); 

          if(jsonField.getKey().equals(“caseClassName”) && jsonField.getValue().asText().indexOf(className)!=-1){ 

            caseTypeName = node.findValue(“caseName”).asText(); 

          } 

        } 

      } 

  } 

  catch(Exception e){ //Do some exception handling here if needed 

  } 

//Default the portal name to WebPortal if not passed 

  if(portalName==null || portalName.trim().length()==0) 

      portalName=”WebPortal”; 

//Merge together all the items to form the URL 

  if (semanticURL.endsWith(“/”))  

     semanticURL = semanticURL+caseTypeName+”/”+caseID+”?portal=”+portalName;  

  else 

     semanticURL = semanticURL+”/”+caseTypeName+”/”+caseID+”?portal=”+portalName;  

return semanticURL; 

Below are the parameters for the function 

Author : Jayachandra Siddipeta, Vice President-Technology, Novitates 

Continue reading