Friday, November 29, 2024

Constellation debug tools

 






Redux : Client cache
XRay : LiveUI Inspector
    PCore.getDebugger().toggleXRay(true)
GetState : Same as Redux tool

Sunday, November 24, 2024

Pega constellation DX component

  1. Install NodeJS
  2. npm i @pega/custom-dx-components
  3. npx @pega/custom-dx-components@~24.2 init
  4. npm run create (To create component)
  5. npm run startStorybook
  6. npm run buildComponent

 For easier organization and maintenance, you can group components in libraries. The component libraries can be created in different rulesets, which in turn can be used for different applications.

When you publish a component to Pega Infinity™, it creates or updates a Rule-UI-Component instance. This instance is pushed by Pega Infinity to the configured Constellation App Static Service. The Rule-UI-Component instances are exported in a RAP file for deployment to other Pega Infinity environments.When a component is published, a zipped version of the component folder is stored as a Pega Infinity Rule-UI-Component rule instance. Pega Infinity automatically pushes this component zip file to the Constellation App Static Service for access during UI rendering.

The naming convention of the component key is <organization>_<library>_<component

  • organization - This value is found in the organization property of the package.json file in your project's root folder.
  • library - This value is requested when the component is created and can also be set as default in the tasks.config.json file.
  • name - This value is requested when the component is created.
Types of constellation DX components
Field
Allows to configure interactive UI elements such as text boxes, buttons, and sliders.
Widget
Improves usability through built-in logic and functionality. For example, the attachment widget allows users to upload documents.
  • PAGE (Portal widgets) - This widget can be used only in landing pages.Example, Todo and App announcements.
  • CASE (Utilities pane widgets) - This widget can be used only in case views.
  • PAGE & CASE (Both) - This widget can be used in portal landing pages, and the Utilities pane for both case and data views. Example, Pulse
Layout template
Provides layouts for the fields and widgets on a form. Grid, Flex are the basic React components for layouts. Layout templates provide slots called Regions. Authors can add fields, field groups, views, widgets into the regions. 
You can create three types of Constellation DX component layout templates using the Constellation DX Component Builder:
  • Details : Applying the Details template renders the child components referenced in the Regions as read-only. Example: Details of Case view and Data type, Partial views use Details template use Details template.
  • Form : Forms are designed to efficiently collect data from the users of your application
  • Page : Page layout templates control the layout of landing pages. 
https://github.com/pegasystems/constellation-ui-gallery
https://github.com/pegasystems/constellation-ui-gallery/releases

Wednesday, November 20, 2024

DORA - DevOps Research and Assessment

  1. Deployment frequency
  2. Lead time for changes : The time it takes from code commit to deployment to production.
  3. Mean time for recovery:
  4. Change failure rate:





Container : Run instances of Docker images. They are isolated environments sharing host OS kernal, ensuring lightweight and consistent execution.
Docker hub : cloud-based registry where docker images are stored and shared publicly or privately

Configuration management with Ansible
Automate infrastructure setup and application configuration
Post-deployment configs, such as setting environment variables or configuring databases.

Monitoring tools
  • Prometheus - Metric collection and alerting
  • Kibana - Log aggregation and analysis
  • Splunk - Operational intelligence and insights
  • Grafana - Dashboards for visualizing metrics

  • Continuous Integration - Code quality, Unit tests, Dependency
  • Continuous Delivery - Pre prod (Manual/Click to deployment to production)
  • Continuous Deployment - Deploy to production
Security -Shift left
  • Left- Plan, Code, Build, Test
  • Right - Release, Deploy and Monior



Saturday, November 16, 2024

Data Flow

 Rule-Decision-DDF (Decision Data Flow)

  1. Real time data flow
  2. Batch data flow
Input
  • Abstract - If this Data flow is configured as destination in other Data flow 
  • Data set 
  • DB Table 
  • Report definition - 
Output 
  • Abstract - If this Data flow is input to other Data flow
  • Data set
  • Data flow 
  • Case 
  • DB table

Processing shapes

  • Compose - Combine data from two sources
  • Convert - Change the class of incoming data
  • Filter
  • Data transform
  • Merge - Similar to UNION in SQL query
  • Strategy
  • Text analyzer
  • Event strategy

Tuesday, November 12, 2024

Database class mapping wizard

  •  pzCreateTableForClass - Activity to create table in Pega DB, and creates Data-Admin-DB-Table instance.
  • Database class mapping wizard - Creates a concrete class and maps to a particular DB table.

  • Classes that inherit from Work- should be either be a class group or belongs to a class group



Job schedulers

 - Adv.Agent are grouped together, and access group configured is applied to all agents in the group.

- Adv.Agents use Agent schedules.

- On disabling an instance of System-JobScheduler-Override.

- Jobschedulers offer both perf statistics & run statistics.



Pega Calendar

  1. Operator
  2. Organization
  3. pyCalendar on WorkPage

JVM - GC

 


Application throughput : Time taken to run the application
Major GC run : The number of times the GC run old gen (tenured) space
Minor GC run : The number of times the GC run young gen space
Heap : System allocated memory for JVM to run all applications
Old gen : The space that contains objects which survived multiple GC runs
Young GC: The space that contains objects which are new/short lived (not survived enuf GC runs)
Metaspace: The space that contains the application metadata (classes + methods). Is not part of Heap
Code cache: Cache that contains code which helps JIT compiler

It starts in the young generation (which itself is divided into multiple spaces - Eden and Survivor) and would eventually end up in the tenured generation if it survived long enough.

Monday, November 11, 2024

Adv. Agent

  •  Assign the records to be processed a sequential number for the jobID as 1,2,3...10
  • Support we have 3 job schedulers, configured with different activities that take batch id as parameter. Agent1 gets parameter value 0, Agent2 value 1 and Agent3 value2.
  • Agent activity checks condition Param.batchID==Page.jobID%3

Friday, November 8, 2024

Case management

  • Duplicate search cases - pyDuplicateSearchCases activity
pyDuplicateSearchCases parameters pyDuplicateCasesReport, CaseMatch rule. It will copy all the matched cases to pyDuplicateCasesReport pagelist.

Approvals

  1. Single level - user reference field, reporting mgr, Participant. Work queue/Business logic
  2. Cascading 
    • Reporting structure - RM, WG Mgr. Approval level is One, All, Custom
    • Authority Matrix - Build Pagelist by using decision table.
      • Create PageList & decision table D-A-O-I class. Evaluate all rows.
      • pxCascadingApproval flow

Thursday, November 7, 2024

Pega SLA

 Flow SLA 

  1. Pega uses internal process flow (pzInternalProcessFlow) with assignment shape & sla parameter. Pega starts this flow in parallel to the current case flow
  2. Creates a new internal assignment (Assign-Internal) and SLA queue item for GOAL time, and System-Queue-ServiceLevel instance which will be process by ServiceLevelEvents agent.

Case SLA

  1. Pega starts OverallSLA flow with Assign-Internal assignment.

Stage SLA
  1. pzInternalStageFlow with Assign-Internal assignment 

Step Level
1. Assign-.AddAssign



  • pxAdjustSLATimes/pxAdjustSLA - This API adjusts the existing goal and deadline times of an assignment.
  • DefineSLATimes Work- to add pySLAName on Work.

Friday, November 1, 2024

Pega common data model

  • 12 Entities (Ex: Common-LDM-Entity-Account)
  • 12 case types : case type per each Entity
  • Data objects that any of the Entities can use. For example, Address
  • Local data storage (Data base tables)
  • API layer for the CRUD operations
  • Data pages that use connectors
  • Data portal for viewing and uploading

  • Common-LDM-Relation-Acct_Con direct inherit from Link-Association-M2M (Link-Association)
  • SelectContactRelationships property is of type PegaList (of Common-LDM-Relation-Acct_Con)

Thursday, October 31, 2024

Field auditing

https://docs-previous.pega.com/case-management/87/extension-point-field-level-auditing

DT - pyFieldLevelAudit : Example : Append to .pyAuditFields -> set .pyPropertyName "pyID"

Packaging
  • A full class of a case type with enabled field-level auditing, for example FLAudit-PegaProjMgmt-Work-UserStory-Epic
  • A class group of a class with enabled field-level auditing, for example FLAudit-PegaProjMgmt-Work
  • DB table instances of the class 'FLAudit-PegaProjMgmt-Work'
Extension point:
  • Create property in FLAudit- class. On the new property form, in the Additional configuration options section, select the Optimize for reporting and Optimize for reporting on descendant classes checkboxes.
  • Save as FLAudit-.pySave activity to FLAudit-<WorkPool> class. Refer Param.ContextPage (for WorkPage context)
Declare trigger -> Queue processor


History (History-Add activity method, AddHistory activity, flow connector shape)
Manage case history writes using decision tree : FilterHistory
FilterHistory application setting : WRITE_NONE/WRITE_SOME/WRITE_ALL
WRITE_NONE - All ootb history writes will be skipped
WRITE_SOME - FilterHistory decision table on the casetype class is considered



Saturday, October 26, 2024

SOLID

 When developing an OO design you should strive to be SOLID.

  1. Single Responsibility
  2. Open/Closed
  3. Liskov Substitution
  4. Interface Segregation
  5. Dependency Inversion
Liskov substitutionif class A is a subtype of class B, we should be able to replace with without disrupting the behavior of our program.
Interface segregationlarger interfaces should be split into smaller ones. By doing so, we can ensure that implementing classes only need to be concerned about the methods that are of interest to them.
Dependency Inversion: The principle of dependency inversion refers to the decoupling of software modules. This way, instead of high-level modules depending on low-level modules, both will depend on abstractions.



Validation

 1) Page-Validate : Validates all properties on the Step page - Mode, Table values, length..etc

2) Property-Validate : Edit-validate rule and/or required. We can list multiple properties.

3) Edit-validate : Referenced in properties, activity (Property-validate) and Validate rules.

  • Client side : If you select the option in the harness level (client side), certain OOTB edit validate has the corresponding javascript code (pega_validators.js). By this way it is working as the client side. But for the custom edit validates which was created as part of the application, it definetly works a server side validation.

      1. Create and test your edit validate rule.
      2. Associate the edit validate rule with a property.
        1. Open the rule form of a property.
        2. On the Advanced tab, under the Use Validate field, select the edit validate rule.
      3. Create and test a JavaScript function that performs the same validation test as the edit validate rule, and has the same name. Follow the structure used in the standard text file rule webwb.pega_validators.js. For example, if you have associated the property with a IsNotFutureDateTest validate rule that checks if the date falls in the future, you need to create a JavaScript function by the same name such as:/* IsNotFutureDateTest */var ruleEditValidate_notFutureDateTest = new validation_ValidationType("notfuturedatetest", ruleEditValidate_isNotFutureDate);ruleEditValidate_notFutureDateTest.addEventFunction("onchange", ruleEditValidate_isNotFutureDate);
      1. Save the JavaScript in a text file rule in your application RuleSet.
      2. Enable client-side validation by clicking the Enable Client Side Validation check box on the Advanced tab of the harness form. For best results use JSP tags and the SmartFrames format for the harness.
      3. Add the text file rule containing the JavaScript function on the Scripts and Styles tab of each harness that can present the field as an input field, that is, in read-write mode.

  •   Edit validate processing operates after edit Input processing and never alters the property value.

 4) Validate (Rule-Obj-Validate): Referenced on FlowAction or Activity.


 

Thursday, October 10, 2024

CSS classes

 https://support.pega.com/discussion/helper-classes-achieve-complex-forms-using-2-column-3-column-inline-wrapping-templates

  1. flex-cell-half
  2. flex-cell-2
  3. flex-cell-3
  4. flex-space-1
  5. flex-space-2

1.  flex-cell-half

This helper class can be used to size the field to half the width of a column.

2.  flex-cell-2

This helper class can be used to make the field occupy 2-columns. In 2-column-inline wrapping template, this helper class can be used to make a field occupy entire width of the row

In 3-column-inline wrapping template this helper class makes a field occupy two columns completely, thus letting only one field in the last column.

3.  flex-cell-3

This helper class can be used only in 3-column inline-wrapping template to make a field occupy entire row.

4.  flex-space-1

This helper class can be used to give a right spacing of 1 column to a field.

5.  flex-space-2

This helper class can only be used in 3-column inline wrapping template, to give right spacing of 2-columns to a field.



Thursday, August 8, 2024

Misc

 ====kill all tracer sessions attached to the rule ==========

String RuleKey = tools.getParamValue("RuleKey");

((PegaAPI)tools).getSystemOperationsProvider().getListenerManagementAPI().terminateTraceForServiceInCluster(RuleKey);

============================================


Friday, July 12, 2024

Create multiple threads

 ParameterPage paramPage = new ParameterPage();

oLog.infoForced("thread:"+tools.getParamValue("thread"));

paramPage.put("ThreadName",tools.getParamValue("thread"));

paramPage.put("Location","pyActivity=DoUIAction&action=createNewWork&className=MyOrg-Lending-Work-Lending&flowName=pyStartCase");

pega_rules_utilities.callActivity(myStepPage,"RedirectAndRun",paramPage);

Monday, June 10, 2024

Read Email attachment

Param.attachmentName=pyAttachmentPage.pyAttachNames(1)

Param.attachmentValue=pyAttachmentPage.pyAttachValues(1)


 String baseDir=tools.getSystemSettings().getFSSetting("initialization/explicittempdir", "" , true, false);

String exportPath= tools.getProperty("pxProcess.pxServiceExportPath").getStringValue().replaceAll("file://web:","");

String AbsoluteFilePath=baseDir+exportPath+tools.getParamValue("FileNameUnique")+".zip";

String line="";

boolean success=true;

java.io.DataOutputStream dos = null;

String zipFilePath = tools.getParamValue("ZipFilePath");

int i=0;

//String zipFileFSPath=null;

try

{

  //Create and write contents to ZIP file

  PRFile zipFile = new PRFile(zipFilePath);

  //zipFileFSPath=zipFile.getAbsolutePath();


  String zipContents=tools.getParamValue("attachmentValue");//.replace("\n","").replaceAll("\\s", "");

  tools.getPrimaryPage().getProperty("pyDescription").setValue(zipContents);

  //byte[] decoded = java.util.Base64.getDecoder().decode(zipContents.getBytes(java.nio.charset.StandardCharsets.UTF_8));

  byte[] decoded = java.util.Base64.getMimeDecoder().decode(zipContents);

  java.io.ByteArrayInputStream bais = new java.io.ByteArrayInputStream(decoded);

  

  dos = new java.io.DataOutputStream(new PROutputStream(zipFile));

  dos.write(decoded);            

  dos.close();


  java.util.zip.ZipFile zippFile=new java.util.zip.ZipFile(AbsoluteFilePath);

  java.util.zip.ZipEntry zipEntry = zippFile.getEntry("Snapshot.json");

  java.io.InputStream inputStream = zippFile.getInputStream(zipEntry);

  java.util.Scanner scanner = new java.util.Scanner(inputStream);

  while (scanner.hasNextLine()) 

    line = line + scanner.nextLine();

  

  //java.util.Enumeration ent = zippFile.entries();

  //while(ent.hasMoreElements()) {

  //  i++;

  //}

  inputStream.close();

  zipFile.delete();

}catch(Exception e){

  

}

tools.getPrimaryPage().getProperty("pyTempText").setValue(i);

tools.getPrimaryPage().getProperty("pyLabel").setValue(AbsoluteFilePath);

tools.getPrimaryPage().getProperty("pyNote").setValue(line);

//Read the json file

Thursday, May 9, 2024

Pega JS functions

Pega close modal dialog of Tabel layout

 "pega.u.d.activeGrid.submitModal"

javascript:event

============================

Auto submit flowaction

--------------------

<pega:include name="AutoSubmit" type="Rule-Obj-HTML"/>

Below is the AutoSubmit HTML rule

<SCRIPT>

var doActionAutoSubmit = function(){

    doSubmit();

  pega.u.d.detachOnload(doActionAutoSubmit);  

}

  

<%

String strMessages = tools.getPrimaryPage().getMessagesAll();

if(strMessages.length() == 0)

{

tools.appendString("pega.u.d.attachOnload(doActionAutoSubmit, false);");

}

%>

</SCRIPT>



=====================================


<Script> function ABCRefresh() { var section = pega.u.d.getSectionByName('SectionName', ''); var theHandle = window.setInterval(function(){pega.u.d.reloadSection(section, 'ActivityName', '', false, false, '-1', false);},120000); } pega.u.d.attachOnload(ABCRefresh, false); </Script>


==============================================

<button onclick="myFunction()" type="button">Click me</button> <script> function myFunction() { var e = window.event; var options = { name: "TestDT", event: e }; pega.api.ui.actions.runDataTransform(options); } </script>




Saturday, May 4, 2024

REST connector exceptions

 "com.pega.pegarules.pub.services.ConnectorException"

"com.pega.pegarules.pub.services.ResourceUnavailableException"

Friday, April 26, 2024

Pega send email notificaiton

 





2.1

String strFileName = tools.getParamValue("OutputFilePath");

PRFile objFile = new PRFile(strFileName); //some error checking

if(objFile.exists())

  objFile.delete();


2.2

call pxGenerateExcelFile

Params - Param.FileName, WEBWB!APPRSVS!XLSX

2.3

String strFileName = tools.getParamValue("OutputFilePath");

PRFile objFile = new PRFile(strFileName); //some error checking

if (!objFile.exists())

{

         attach = false;

} if(!objFile.isFile())

{

         attach = false;

}

tools.putParamValue("OutputLocation",objFile.getName()); if (!objFile.canRead())

{

         attach = false;

    throw new PRRuntimeException("Can't continue with file upload. File \"" + strFileName + "\" is unreadable.");

} //read the file into a buffer.

java.io.DataInputStream dis = null;

byte buffer [] = null;

try

{

    // dis = new java.io.DataInputStream(new java.io.FileInputStream(objFile));    

    dis = new java.io.DataInputStream(new PRInputStream(objFile));

    buffer= new byte[dis.available()];                

    dis.readFully(buffer);

    dis.close();

}

catch (Exception e)

{

    attach = false;

         throw new PRRuntimeException("Can't continue with file upload. Can't read File \"" + strFileName + "\"");            

} //encode the file to Base64 so that we can store it on the database

strFileData = Base64Util.encodeToString(buffer);

if (strFileData == null)

{

         attach = false;

         throw new PRRuntimeException("Can't continue with file upload. Couldn't encode the file to Base64 so that we can store it on the database");            

}

2.5

Page-new att (Embed-EmailAttachment)

2.6

Property-set att

.pyDecode=true

.pyData=local.strFileData

.pyName=Param.FileName


2.7 atts (Data-EmailAttachments)

Page-copy 

from: att

to: atts.pyAttachments(<APPEND>)


Param.AttachmentPage=atts


===================================

java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();

java.util.zip.ZipOutputStream logical_zip = null;

class ParamHelper {

  Boolean getBooleanValue(String param){

    String value = tools.getParameterPage().getString(param);

    if("true".equalsIgnoreCase(value)){

      return true;

    }else if("false".equalsIgnoreCase(value)){

      return false;

    }else{

      return null;

    }

  }

}

ParamHelper params = new ParamHelper();


try {

    // Create a ZIP archive output stream with no compression

    logical_zip = new java.util.zip.ZipOutputStream(baos);

} catch (Exception e) {

    throw new PRRuntimeException("Cannot initialize archive: " + e.getMessage());

}


ClipboardProperty cpResults = tools.findPage("pyWorkPage").getProperty("SendFiles");


try {

    for (Iterator instPgList = cpResults.iterator(); instPgList.hasNext();) {

        ClipboardProperty objOneRow = (ClipboardProperty) instPgList.next();

        ClipboardPage objOneRowPage = objOneRow.getPageValue();


        String strOutputPRFileName = objOneRowPage.getProperty("AttachStream").getStringValue();

        byte[] data = Base64Util.decodeToByteArray(strOutputPRFileName);

        String strOutputFileName = objOneRowPage.getProperty("AttachName").getStringValue();


        

     boolean isSubFolderExist = Boolean.parseBoolean(objOneRowPage.getProperty("IsSubFolderExist").getStringValue());

    


        // Determine the folder path based on the isSubFolderExist flag

        String folderPath;

        if (isSubFolderExist) {

            folderPath = "SubFolder/";

        } else {

            folderPath = "";

        }


        // Add each file to the appropriate folder in the ZIP archive

        String fileFolderPath = folderPath + strOutputFileName;

        try {

            logical_zip.putNextEntry(new java.util.zip.ZipEntry(fileFolderPath));

            logical_zip.write(data);

            logical_zip.closeEntry();

        } catch (java.io.IOException e) {

            throw new PRRuntimeException("Cannot add file to archive: " + e.getMessage());

        }

    }


    // Send the entire ZIP archive to the client

   

  String zipFileName = tools.getParameterPage().getString("ZipFileName");

  zipFileName = zipFileName + ".zip";

    try {

        logical_zip.close();

        baos.close();

        tools.sendFile(baos.toByteArray(), zipFileName, false, null, true);

    } catch (java.io.IOException e) {

        throw new PRRuntimeException("Error while sending: " + e.getMessage());

    }

} catch (Exception ex) {

    throw new PRRuntimeException("Error: " + ex.getMessage());

}

============================================================

Thursday, April 18, 2024

Binary in the REST response

 https://docs-previous.pega.com/data-management-and-integration/87/configuring-rest-connector-receive-binary-attachments


Configuring a REST connector to receive binary attachments

Updated on April 6, 2022

Pega Platform can receive attachments regardless of the content type or response type. Configure a REST connector to receive attachments when your application connects to a service that responds with a binary stream, for example, a PDF file or XLS file.

Before you begin:
  1. Configure your REST connector to map the response to the clipboard.
    1. On the Methods tab of your REST connector, in the GET section, click the Response tab.
    2. In the Message data section, in the Map to field, select Clipboard.
    3. In the Map to key field, enter the map to key property and then click the rule opener.
      For example: .binaryxls
      Result: The Property Record Configuration page is displayed.
  2. Configure the java object property type and the map to key.
    1. On the Property Record Configuration page, enter a name for the property, choose a class that you want to associate with the property, and select a ruleset and a ruleset version in which you want to store the property.
      For more information, see Properties.
    2. Click Create and open.
    3. On the General tab, in the Property type section, click ChangeJava Object.
    4. Click Save.
    5. Click Save on the Connect REST rule form.
  3. In the activity, define the page on which the response is mapped.
    1. On the Steps tab of the activity, in the Method field, press the Down arrow key and select Page-New.
      For more information, see Page-New method.
    2. In the Step page field, press the Down arrow key and select the name of the page to be created by this method.
      For example: BinaryAttachment
    3. On the Pages & Classes tab, enter the name of the page that you reference in step 3b and the class to which the page belongs.
  4. Call the service from the activity by using the Connect-REST method.
    1. On the Steps tab of the activity, click Add a step.
    2. In the Method field, press the Down arrow key and select Connect-REST.
    3. In the Method Parameters section, in the ServiceName field, enter the name of the service that you use to retrieve the attachment (the REST connector you configure in step 1), and then click the rule opener.
    4. In the MethodName field, select GET.
    5. In the ExecutionMode field, select Run.
    6. Click Add a step.
    7. In the Method field, press the Down arrow key and select Java.
    8. In the Method Parameters section, enter the following:
      tools.sendFile((byte[])myStepPage.getObject("Name_defined_in_response_clipboard_map_to_key "), "test.xls", false, null, true);
      where ("Name_defined_in_response_clipboard_map_to_key") is the map to key property that you enter in step 1c.
    9. Click Save.

Have a question? Get answers now.

Visit the Support Center to ask questions, engage in discussions, share ideas, and help others.

Did you find this content helpful?

Want to help us improve this content?

Contact us