Friday, November 29, 2024
Constellation debug tools
Sunday, November 24, 2024
Pega constellation DX component
- Install NodeJS
- npm i @pega/custom-dx-components
- npx @pega/custom-dx-components@~24.2 init
- npm run create (To create component)
- npm run startStorybook
- 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.
- 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
- 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.
Wednesday, November 20, 2024
DORA - DevOps Research and Assessment
- Deployment frequency:
- Lead time for changes : The time it takes from code commit to deployment to production.
- Mean time for recovery:
- Change failure rate:
- 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
- Left- Plan, Code, Build, Test
- Right - Release, Deploy and Monior
Saturday, November 16, 2024
Data Flow
Rule-Decision-DDF (Decision Data Flow)
- Real time data flow
- Batch data flow
- Abstract - If this Data flow is configured as destination in other Data flow
- Data set
- DB Table
- Report definition -
- Abstract - If this Data flow is input to other Data flow
- Data set
- Data flow
- Case
- DB table
- 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.
JVM - GC
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
Approvals
- Single level - user reference field, reporting mgr, Participant. Work queue/Business logic
- 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
- Pega uses internal process flow (pzInternalProcessFlow) with assignment shape & sla parameter. Pega starts this flow in parallel to the current case flow
- 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.
- Pega starts OverallSLA flow with Assign-Internal assignment.
- pzInternalStageFlow with Assign-Internal assignment
- 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
- 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'
- 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)
Saturday, October 26, 2024
SOLID
When developing an OO design you should strive to be SOLID.
- Single Responsibility
- Open/Closed
- Liskov Substitution
- Interface Segregation
- Dependency Inversion
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.
- Create and test your edit validate rule.
- Associate the edit validate rule with a property.
- Open the rule form of a property.
- On the Advanced tab, under the Use Validate field, select the edit validate rule.
- 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);
- Save the JavaScript in a text file rule in your application RuleSet.
- 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.
- 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.
4) Validate (Rule-Obj-Validate): Referenced on FlowAction or Activity.
- Edit validate processing operates after edit Input processing and never alters the property value.
Thursday, October 10, 2024
CSS classes
https://support.pega.com/discussion/helper-classes-achieve-complex-forms-using-2-column-3-column-inline-wrapping-templates
- flex-cell-half
- flex-cell-2
- flex-cell-3
- flex-space-1
- 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());
}
============================================================
Tuesday, April 23, 2024
Override SLA agent access group (System-Queue-Servicelevel)
Param.queueAccessGrp=Admin:AccessGroup in NewDefaults activity
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
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.
- Create a REST connector to connect to the service that is responding with a binary attachment. For more information, see Creating a Connect REST rule.
- Create an activity. For more information, see Creating an activity.
- Configure your REST connector to map the response to the clipboard.
- On the Methods tab of your REST connector, in the GET section, click the Response tab.
- In the Message data section, in the Map to field, select Clipboard.
- 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.
- Configure the java object property type and the map to key.
- 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.
- Click Create and open.
- On the General tab, in the Property type section, click ChangeJava Object.
- Click Save.
- Click Save on the Connect REST rule form.
- 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.
- In the activity, define the page on which the response is mapped.
- 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.
- 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 - 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.
- On the Steps tab of the activity, in the Method field, press the Down arrow key and select Page-New.
- Call the service from the activity by using the Connect-REST method.
- On the Steps tab of the activity, click Add a step.
- In the Method field, press the Down arrow key and select Connect-REST.
- 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.
- In the MethodName field, select GET.
- In the ExecutionMode field, select Run.
- Click Add a step.
- In the Method field, press the Down arrow key and select Java.
- In the Method Parameters section, enter the following:where ("Name_defined_in_response_clipboard_map_to_key") is the map to key property that you enter in step 1c.
tools.sendFile((byte[])myStepPage.getObject("Name_defined_in_response_clipboard_map_to_key "), "test.xls", false, null, true);
- Click Save.
Have a question? Get answers now.
Visit the Support Center to ask questions, engage in discussions, share ideas, and help others.
Want to help us improve this content?